gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > C++ : dooble pointer question

#149818 - ghuldan - Fri Jan 25, 2008 5:51 pm

Hi,
I want to use an array of (int*), but i have some problems, here is a simplified code ... i just want to theorize, not make you debug my code.

Code:
class NoName {
  int** array;
 
  NoName() {
      this->array = (int**)malloc(sizeof(int*) * 4);
  }
  void fillArray();
}
//----------------------
void NoName::fillArray() {
  fill( &(this->array[0]) );

}
//----------------------------------
void fill(int** tab) {
  (*tab) = new int[100];
  for (int i = 0...)
      (*tab)[i] = 42;
}


when i try to create and fill one of the (int*) of NoName::array, only the first element of the array (here NoName::array[0][0]) is filled, the rest is nonsense. I think i must be wrong in calling the fill function in NoName::fillArray()

I also tried with :

Code:
//----------------------
void NoName::fillArray() {
  fill( this->array, 0 );

}
//----------------------------------
void fill(int** tab, int num) {
  tab[num]= new int[100];
  for (int i = 0...)
      tab[num][i] = 42;
}


and

Code:
//----------------------
void NoName::fillArray() {
  this->array = fill( this->array, 0 );

}
//----------------------------------
int** fill(int** tab, int num) {
  tab[num]= new int[100];
  for (int i = 0...)
      tab[num][i] = 42;
  return tab;
}


I would really want to know what's wrong here.

Thanks in advance.

#149829 - sajiimori - Fri Jan 25, 2008 8:09 pm

Ok, so you've got an irregular 2D array, where each row can have a different length. (If you only need a regular 2D array, use a single call to 'new' to allocate the whole thing.)

I can't say what the problem is because the code is too obscure for my poor brain. ;) Pointers to pointers are already confusing, but having a dual meaning of "pointer to pointer" sends it off the deep end in this code: sometimes it means a 2D array, and sometimes it means an output parameter.

I'd suggest replacing the 'malloc' call with 'new'. It's less error prone, nicer looking, and mixing 'malloc' and 'new' is considered iffy in general.

Going further, boost::scoped_array would make your code a lot less error prone, and it costs basically nothing in terms of efficiency.

fillArray() could also be re-envisioned as something like this:
Code:
int* createArray();

void NoName::fillArray()
{
  // Use return values instead of output parameters.
  array[0] = createArray();
}

#149893 - gmiller - Sat Jan 26, 2008 2:51 pm

sajiimori is correct .... you allocated an array of **in pointers and then wanted to create an array that each pointer "points" to.

array[x] points to an *int so you need to allocate memory and fill in the pointer. The mixing of malloc and new is risky in general because your runtime library might not use the same underlying code to manage the heap which could cause cross pointer problems (two different heap pointers referencing the same memory or a partial overlap).

When I need aligned memory allocation for hardware data types (such as SIMD) I override new with malloc in VS so I can use the aligned malloc to create the memory on the heap at the required 16 byte aligned address. So the risk is not always an issue depending on your tools.

sajiimori approach is what you need to do (create the array in fill or just prior to calling fill ... depends on how you want to do it.

Sorry for the long winded reply ...