two dimensional array

A

Axter

Bushido said:
(skeptical) I don't know. That way seems to suck up more memory that
it should. Especially the lines where the pool is used.

One thing I certainly disagree with is the Free2DArray.
The problem with using
delete[] *Array;
is that it only deletes what ever is at Array[0]. Any other data in
in that row is still allocated. Thus, a memory leak is present at
Array[1], Array[2], etc.


There is no memory leak using that method. That's the beauty of it.
You can delete the entire array with on call to delete.
You can easily test this out by the following test program.
class foo
{
public:
foo(){cout << "foo" << endl;}
~foo(){cout << "~foo" << endl;}
};

int main(int argc, char* argv[])
{
foo ** foo_arr = Allocate2DArray<foo>(2, 3);
Free2DArray(foo_arr);


If you run the above program, you'll see six constructor calls, and six
destructor calls.
If there was a leak, there would be some missing destructor calls.
I also noticed your way used much more memory that it should. Perhaps
this is why you prefere vectors over arrays.

In your Allocate2DArray, you created
T *pool = new T [nRows * nCols];
This statment says you want to allocate (nRows * nCols) space IN EACH
ROW!
You then renamed pool curPtr. This mean pool could drop all that
allocated space at the end of Allocate2DArray and could not put it back
in Free2DArray because you used the "new" operator.

This is also incorrect. In my code I'm only doing two calls to new.
The first call creates an array of pointers.
The second call creates an array of the target type.
It uses exactly the same amount of memory space as your original code.
You can verify this via profile test.

Remember, when you do a delete, you need to do the delete on the
pointer you got back when using new. That what this code does.

There is no memory leak, and this code is much more efficient, because
it doesn't have to call new and delete over and over again for each
row.

It makes one call to new, that creates a pool of memory.
Then it iterates through the pool of memory, and assign sections that
are divided by the quantitiy of rows.

I know the code is a little hard to understand, and can be misleading
as to what it's doing, but if you run it and test it, you'll see that
it does exactly what it's suppose to do, and it does it more
efficiently.
 
A

Angad

Hi
I'll say one thing here. Given the following situations
1. The data type of the elements is primitive/basic
2. One-time memory allocation and deallocation is required in any
object
I think the BEST way is to manually allocate and deallocate memory by
new and delete. I'm sure vector implements lots of bound checks, and
that increases allocation code itself, forget about manipulations. I'm
an undergrad, and I've started using vectors wherever necessary, only
because it reduces my coding drastically, so that I can concentrate on
the algorithm of the problem given to me.
Please comment

ps: to Val: I didn't endorse std:valarray because I haven't used it
much. Does it involve lesser coding than vectors or more?
 
K

Karl Heinz Buchegger

Angad said:
Hi
I'll say one thing here. Given the following situations
1. The data type of the elements is primitive/basic
2. One-time memory allocation and deallocation is required in any
object
I think the BEST way is to manually allocate and deallocate memory by
new and delete. I'm sure vector implements lots of bound checks, and
that increases allocation code itself, forget about manipulations.

Usually all of that is NOT true.
The difference in using 'vector' versus 'homemade manually allocated
arrays' is that the former works out of the box while the later
gives lots of troubles. In terms of runtime both versions usually
are next to each other, sometimes std::vector is faster, sometimes
the homegrown version is faster. But they are usually that close
to each other that it really doesn't matter what you use, that is:
if execution speed is your only concern.
 
A

Alvin

Bushido said:
It's not that I'm not allowed to use the vector class, I'm just not
interested in using vectors. I'm more comfortable with Arrays and
Pointers

I like Angad's method.

Here is what I'd really like to do with his codes:

class Matrix{
public:
Matrix(int rows = 4, int cols = 4){
setDims(rows,cols);
int **p ;
p = new int *[getRows()] ;
for( int i = 0 ; i < getRows() ; i++ ){
p = new int[getCols()];
};
};
Matrix &setDims(int rows,int cols){setRows(rows);setCols(cols);};
Matrix &setRows(int rows){this->rows = rows; return *this;};
Matrix &setCols(int cols){this->cols = cols; return *this;};
int getRows() const {return rows;};
int getCols() const {return cols;};
Matrix printMatrix() const {
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
cout << this[j] << " "; // I know this is incorrect, but I'm
just using it
// to illustrate the concept. Please correct if I am wrong.
};
cout << endl;
};
};
Matrix &setIdentity(){
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
this[j] = (i == j);
};
};
}; // Identity matrix
~Matrix(){
for( int i = 0 ; i < getRows() ; i++ ){
delete [] p ;
};
delete [] p ;
};
private:
int rows, cols;
};

// such that I can do this

int main(){
Matrix m(4,4); // yes I know I already declared defaults
// but I'm just using this as an example
m.setIdentity().printMatrix();
return 0;
};

The desired output should be

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1


Just an idea, instead of printMatrix() you could make your matrix directly
with cout as in:

cout << m << endl;

I use this function in my Matrix2D...I think I got if from the C++-Lite FAQ:

(m and n represent the dimension of the Matrix2D as in: m x n)

friend ostream& Matrix2D::eek:perator<<(ostream &out, const Matrix2D &matrix2d)
{
for(int i = 0; i < matrix2d.m; i++)
{
for(int j = 0; j < matrix2d.n; j++)
out << matrix2d.matrix[j] << " ";
out << endl;
}

return out;
}
 
O

Old Wolf

Angad said:
Yes, I agree that vectors simplify the matter a lot by reducing our
coding, but I must say that they add to a lot of unnecessary code to
the executable code.

What unnecessary code do they add, for example?
Compile time increases manyfold (I'm talking from a personal
experience).

Enable pre-compiled headers in your compiler.
I'd say, use vectors only when basic data types cannot be used....

I'd say that tracking down even one memory allocation bug in your
code would take longer than adding up all the extra compile time
caused by using vectors.
As for the freeing of the memory, the code is:

for( int i = 0 ; i < ROWS ; i++ )
delete [] p ;
delete [] p ;

This code will definitely be faster than using vectors...


What makes you think that?
It seems likely to me that the vector code will boil down to
exactly that series of deletes. You could examine the
assembly generated by your compiler, and see what the difference
is.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top