Hi,
today I had to code something like this:
unsigned int var1; unsigned int var2;
char **myArray = new char[var1][var2];
As you probably know, no C++ compiler is going to accept this; there will be an error about some non constant value as second array dimension. (g++ delivers:
... error: ‘numOfCols’ cannot appear in a constant-expression)
Ok, the straight forward solution would be to use a STL container, for example:
std::vector< std::vector<char> >
But I'm having a special case where I really do not want to use the STL containers. Luckily enough, there's a solution:
#include <iostream>
using namespace std;
class ArrayTest{
public:
ArrayTest(const unsigned int numOfRows, const unsigned int numOfCols)
{
unsigned int i, j;
this->numRows = numOfRows;
this->numCols = numOfCols;
this->mat = new char*[this->numRows];
for (i = 0; i < this->numRows; i++)
{
this->mat[i] = new char[this->numCols];
for (j = 0; j < numOfCols; j++)
{
this->mat[i][j] = (j%10) + 48;
}
}
};
~ArrayTest()
{
delete [] this->mat;
};
void print()
{
unsigned int i, j;
for (i = 0; i < this->numRows; i++)
{
for (j = 0; j < this->numCols; j++)
{
cout << this->mat[i][j] << " ";
}
cout << "\n";
}
cout << "\n";
};
private:
unsigned int numRows;
unsigned int numCols;
char ** mat;
};
int main(int argc, char **argv)
{
ArrayTest myObj(10,10);
myObj.print();
return(0);
}
It compiles beautifully, the print looks as nice as a demo application print can but it's got a bad error: if you run it through valgrind, you'll discover a memory leak. Reading the code carefully, you'll see that it violates the rule: Call
everytime you call:
You'll have to rewrite the destructor like this:
...
~ArrayTest()
{
unsigned int i;
for (i = 0; i < this->numRows; i++) { delete [] this->mat[i]; }
delete [] this->mat;
};
...
This compiles beautifully, the print looks as nice as a demo application print can and the memory leak is closed. (Ask valgrind! :-) )
Calling the
operator for each row isn't the nicest thing to do, using a STL container would be preferable in most situations. But if you really think you can't, this is a valid alternative as long as you craft the destructor carefully.
Bye, Simon