Search code examples
c++borland-c++

Defining an AnsiString matrix in Borland C++ builder without knowing the size


I have the following code:

int cl = value1;
int fl = value2;
AnsiString **mat = NULL;
mat = (AnsiString **)malloc(sizeof(AnsiString)*fl);
for(int i=0; i < fl; i++) mat[i]=(AnsiString *)malloc(sizeof(AnsiString)*cl);
int count = 0;
for (int f=0; f<fl; f++){
      for (int c=0; c<cl; c++){
          if (count < str.Length()) mat[f][c]=str[++count];
          else mat[f][c]='X';
      }
}

But it is not working. I read several "how to's" but I can't find the right way to do it.

I'm pretty noob with this malloc thing so any advice/help will be apreciated.

Thank you very much in advance.


Solution

  • Never allocate non-POD objects using malloc, like you are:

    mat[i]=(AnsiString *)malloc(sizeof(AnsiString)*cl)
    

    The constructor of the object won't be called (you would have to call it manually afterwards using the placement new operator). The line above is just pleading for a memory error.

    Use the new[] operator instead:

    AnsiString **mat = mat = new AnsiString*[fl];
    for(int i=0; i < fl; i++) mat[i] = new AnsiString[cl];
    

    You can still access an object using mat[m][n], where m is a row number and n is a column number.

    Don't forget to free the memory using delete[] when done:

    for(int i=0; i < fl; i++) delete[] mat[i];
    delete[] mat;
    

    However, using new[]/delete[] like this is still error prone if you are not careful. I recommend you to use a std::vector instead, and let it manage all of the memory for you:

    std::vector< std::vector<AnsiString> > mat( f1 );
    for( i = 0; i < f1; ++i ) mat[i].resize( c1 );
    

    You can still access an object using mat[m][n], but you don't have to worry about freeing anything as it will free itself automatically when it goes out of scope.