Astaboom Astaboom - 9 days ago 6
C++ Question

arrays using pointers in c++: segmentation fault when accessing the returned array

I'm new to C++ and I'm trying to build a 3 dimensional array using a pointer to a pointer to a pointer. I am sure there are more efficient ways in doing so, but I am trying to understand pointers at the moment.

As example code, I originally had the following piece, which worked fine, allocating, initializing, and releasing the memory.

void builder(int aSize1, int aSize2, int aSize3)
{
int i1, i2, i3;
int ***frequencies;

cout << "allocation started ..." << endl;
frequencies = new int** [aSize1+1];
for (i1=0; i1<=aSize1; i1++){
frequencies[i1] = new int*[aSize2+1];
for (i2 = 0; i2 <= aSize2; i2++)
{
frequencies[i1][i2] = new int [aSize3 + 1];
}
}
cout << "allocation done" << endl;
cout << " " << endl;

cout << "before initialization" << endl;
for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
for(i3 = 0; i3 <= aSize3; i3++)
{
frequencies[i1][i2][i3]= (i1 * i2) % 10;
}
}
}
cout << "after initialization" << endl;
cout << " " << endl;

/* the "destroyer" part */

cout << "deleting ..." << endl;

for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
delete [] frequencies[i1][i2];
}
}

for (i1=0; i1<aSize1; i1++){
delete [] frequencies[i1];
}
delete [] frequencies;
cout << "deleting done" << endl;

}


I wanted to up the ante by splitting the code above into several parts, so that I could use the initialized array in the
main()
function of my program (just to see if I can access them there as well). So, I ended up doing the following

The header file:

void builder(int aSize1, int aSize2, int aSize3, int*** frequencies)
{
int i1, i2, i3;
//int ***frequencies;

cout << "allocation started ..." << endl;
frequencies = new int** [aSize1+1];
for (i1=0; i1<=aSize1; i1++){
frequencies[i1] = new int*[aSize2+1];
for (i2 = 0; i2 <= aSize2; i2++)
{
frequencies[i1][i2] = new int [aSize3 + 1];
}
}
cout << "allocation done" << endl;
cout << " " << endl;

cout << "before initialization" << endl;
for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
for(i3 = 0; i3 <= aSize3; i3++)
{
frequencies[i1][i2][i3]= (i1 * i2) % 10;
}
}
cout << **(frequencies[i1]+2) << endl;
}
cout << "after initialization" << endl;
cout << " " << endl;

}

void destroyer( int aSize1, int aSize2, int aSize3, int*** frequencies )
{
int i1, i2;

cout << "deleting ..." << endl;

for (i1=0; i1<=aSize1; i1++){
for(i2=0; i2<=aSize2; i2++){
delete [] frequencies[i1][i2];
}
}

for (i1=0; i1<aSize1; i1++){
delete [] frequencies[i1];
}
delete [] frequencies;
cout << "deleting done" << endl;
}


and my
main()
where I try to access the 3d array in a fruitless effort.

int main()
{
int aSize1 = 10;
int aSize2 = 10;
int aSize3 = 10;
int*** freq;

builder(aSize1, aSize2, aSize3, freq);
cout << "builder finished" << endl;
cout << **(freq[1]+2) << endl;
destroyer( aSize1, aSize2, aSize3, freq);
}


When I compile this, the "builder" function runs fine, but I get a segmentation fault whenever I try to access the 3d array in the main function. I would expect this to work because I have read it in my book that if something is passed by reference using a pointer to a function, the function would have the power to manipulate it. Also, I expected that I would need to dereference the 3d array 3 times (i.e. ***freq) in order to correctly access the elements, but the compiler gets mad at me for trying to do so and blurts out


myBuilder.cpp:42:17: error: indirection requires pointer operand ('int' invalid)
cout << ***(frequencies[i1]+1) << endl;


I know this is a newb question, but any help will be appreciated!

Answer

The frequencies pointer in builder and destroyer is a copy of the freq pointer in main. So setting it in builder does not change the (uninitialized) pointer in main. You want a reference to pointer instead:

void builder(int aSize1, int aSize2, int aSize3, int***& frequencies);

And for your levels of indirection, note that if freq is an int***, then freq[1] is an int**.