I got a segfault error while executing this code. It prints the largest of 5 numbers, and those numbers are stored in heap-memory.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int *)malloc(5 * sizeof(int));
*ptr = 5;
*(ptr + 1) = 7;
*(ptr + 2) = 2;
*(ptr + 3) = 9;
*(ptr + 4) = 8;
int *ptr_max = (int *)malloc(sizeof(int));
*ptr_max = 0;
for (int i = 0; i < 5; i++) {
if (*ptr_max < *ptr) {
*ptr_max = *ptr;
ptr++;
} else
ptr++;
}
printf("%d\n", *ptr_max);
free(ptr);
free(ptr_max);
return 0;
}
I want to know why exactly I got this error from the above code. Please can anyone explain it to me?
The real problem lies when you are free()
-ing the ptr
. Once, you increment a pointer its address jumps to next address allocated by malloc()
. Always make sure that *ptr
is same as ptr[0]
. So, to fix this issue, you can decrement the ptr
by 5, or create a copied pointer.
Example of address given to free()
, they are not pointing to the same memory block:
Before decrementing 0x213f2b4
After decrementing 0x213f2a0
The reason for decrementing by 5
, is the difference between these two hexadecimal values which is 20
, same as sizeof(int) * 5
.
ptr -= 5;
OR
You can create a copy of your pointer and then perform operations on that copied one:
int *my_copied_ptr = ptr; // you don't need to free this pointer
Then, free()
them:
free(ptr);
free(ptr_max);
Now, to avoid these mistakes further in a large code bases, try using []
operator like this:
ptr[0] = 5;
ptr[1] = 7;
ptr[2] = 2;
ptr[3] = 9;
ptr[4] = 8;