I have created this code to test one error, that I get in my main code, and it shares the same problem. I'm always getting either segmentation fault or corrupted data (zeros or strange numbers).
Here is the code:
int *p=NULL;
int func (int **point);
int main() {
int num = 5647;
p = malloc(sizeof(int)*2);
p[0] = num;
p[1]= 657;
printf("%d\n", p[0]);
printf("%d\n", p[1]);
func(&p);
printf("%d\n", p[0]);
printf("%d\n", p[1]);
printf("%d\n", p[2]);
printf("%d\n", p[3]);
return 0;
}
int func (int **point){
*point = realloc(*point,sizeof(int)*4);
if (*point==NULL){
printf("\n abort \n");
exit(0);
}
*point[0] = 867;
*point[1]= 777;
*point[2] = 67;
*point[3]= 77;
}
I'm getting the segmentation fault on the *point[1]=777;
. If I'm trying to do like point[1]=777;
I'm getting wrong data. With any changes in int func (int **point);
or func(&p);
I'm getting segmentation fault on realloc
.
Please advise, I have read information about double pointers and tried to follow all solutions I found, but every time I'm getting this error.
Your problem is operator precedence, change *point[0]
to (*point)[0]
and so forth.
What you have right now is *(point[0])
. You treat a pointer to a single element as a pointer to multiple consecutive elements and then dereference some indeterminate value as an address. This results in undefined behavior, which luckily for you manifests as a crash.
After the change you first dereference point
and then use that address to index into consecutive elements you allocated.
Two suggestions for improvement:
Don't assign the result of realloc
directly to *point
. If the call fails, then you leak the original memory. Assign it to a temporary first for verification.
Also, try not to repeat types. Instead of sizeof(int)
try for sizeof(**point)
, i.e whatever the output buffer is supposed to point at. That way you won't have silent errors in your code if you change the type from int
to something else.
void *point_check = realloc(*point,sizeof(**point)*4);
if (point_check == NULL){
printf("\n abort \n");
exit(0); // If this ever returns instead of exit, `*point` will not leak
}
*point = point_check;