I'm currently messing around with c I'm having a few hiccups in the pointer usage and syntax area.
Below, i am (trying) to create an array of pointers to integer arrays, then, direct each pointer to an array created via malloc().
After the arrays have been created i then for loop through each cell, assigning a value.
Now, all of this seems to be working, but when it comes to then using free() to take back the memory, the program crashes.
I have noticed that if i malloc() the array memory and then immediately call free() on them, the program executes without problem. When however I malloc(), assign values and THEN call free() the crash will occur. (Segmentation fault).
Below is the code that works, malloc() then immediately free()ing
int (*ptrArr[5])[5];
for(int i=0; i<5; i++)
ptrArr[i] = malloc(sizeof(int) * 5);
for(int i=0; i<5; i++)
printf("ptrArr[%d][%x]->[%x]\n", i, &ptrArr[i], &*ptrArr[i]);
printf("\n");
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
printf("[%x](%2d) | ", &*ptrArr[i][j], *ptrArr[i][j]);
}
printf("\n");
}
for(int i=4; i>=0; i--)
free(ptrArr[i]);
the above executes as i expected it to, but when I assign values to cells and then try and call free afterwards, a segmentation fault is generated:
int (*ptrArr[5])[5];
for(int i=0; i<5; i++)
ptrArr[i] = malloc(sizeof(int) * 5);
for(int i=0; i<5; i++)
printf("ptrArr[%d][%x]->[%x]\n", i, &ptrArr[i], &*ptrArr[i]);
printf("\n");
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
printf("[%x](%2d) | ", &*ptrArr[i][j], *ptrArr[i][j]);
}
printf("\n");
}
int loop = 5;
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
*ptrArr[i][j] = (loop + (i*j));
++loop;
}
}
printf("\n");
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
printf("[%x](%2d) | ", &*ptrArr[i][j], *ptrArr[i][j]);
}
printf("\n");
}
for(int i=4; i>=0; i--)
{
printf("Freeing ptrArr[%x]\n", i);
free(ptrArr[i]);
}
I think I'm either misunderstanding the
int (*ptrArr[5])[5];
declaration, which I intended was an array of 5 pointers, each pointing to an integer array, or im not assigning values to cells correctly, instead, corrupting memory which causes the free() to fail.
Any help would be appreciated, I hope the question is clear and succinct.
Thanks.
The way I approach this type of problem is to print out the sizeof
the various suspects, like this
int (*test[5])[5];
printf( "%zu ", sizeof(test) );
printf( "%zu ", sizeof(test[0]) );
printf( "%zu\n", sizeof(test[0][0]) );
The result is 40 8 20
. (Note that on my machine an int
is 4 bytes and a pointer is 8 bytes.)
So that tells me that test
is an array of 5 pointers. It logically follows that test[0]
is a single pointer. But what's interesting is that test[0][0]
is an array of 5 ints.
If I add the following line of code
printf( "%zu\n", sizeof(test[0][0][0]) );
the output is 4, i.e. test[0][0][0]
is a single int
. From that we conclude that the declaration int (*test[5])[5]
is declaring a three dimensional array, which is not what you intended.
So let's try a simpler declaration, like this
int (*test)[5];
printf( "%zu ", sizeof(test) );
printf( "%zu ", sizeof(test[0]) );
printf( "%zu\n", sizeof(test[0][0]) );
The output is 8 20 4
, which is to say that test
is a single pointer, test[0]
is an array of 5 ints, and test[0][0]
is a single int
. We conclude that int (*test)[5]
declares a two dimensional array.
The next question is how to we allocate memory for the array. If we do this
test = malloc( 5 * sizeof(int) );
then we have an array that has 1 row and 5 columns, basically a one-dimensional array.
To get a two-dimensional array with N
rows, we need
test = malloc( N * 5 * sizeof(int) );
Then we can fill, print, and free the array like this
int N = 5;
for ( int row = 0; row < N; row++ )
for ( int col = 0; col < 5; col++ )
test[row][col] = (row+5)*10 + col;
for ( int row = 0; row < N; row++ )
{
for ( int col = 0; col < 5; col++ )
printf( "%2d ", test[row][col] );
printf( "\n" );
}
free( test );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With