Search code examples
cpointersdynamic-memory-allocation

I have to ask about aborted(core dumped) error i get from this code


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?


Solution

  • 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;