Search code examples
cmemorymallocheap-memoryfree

malloc/free() with error signal 6


Here is a basic stack implementation code. However, it generates signal abort.

int *arr;
int size = 2;
int top = 0;

int pop() {

    int i;
    if (top <= size / 4) {
        int *arr2 = (int*)malloc(sizeof(int) * size / 2);
        for ( i = 0; i < size; i++)
            arr2[i] = arr[i];
        free(arr);
        arr = arr2;
        size /= 2;
    }
    return arr[--top];
}

void push( int a) {

    int i;
    if (top >= size) {
        int *arr2 = (int*)malloc(sizeof(int)*size * 2);
        for ( i = 0; i < size; i++)
            arr2[i] = arr[i];
        free(arr);
        arr = arr2;
        size *= 2;
    }   
    arr[top++] = a;
}

Here is the output:

*** glibc detected *** a.out: free(): invalid pointer: 0x0804a030 ***

and the debug data shows aborted sig 6 The interesting thing is that it shows the line of free() but As 4386427 said, the problem is accessing out of bounds of memory while copying arr2 of size

enter image description here

0 0xffffe410 in __kernel_vsyscall ()

1 0xb7e8a7d0 in raise () from /lib/libc.so.6

2 0xb7e8bea3 in abort () from /lib/libc.so.6

3 0xb7ebff8b in __libc_message () from /lib/libc.so.6

4 0xb7ec5911 in malloc_printerr () from /lib/libc.so.6

5 0xb7ec6f84 in free () from /lib/libc.so.6

6 0x080484a0 in pop () at stacks_eng.c:14

7 0x0804867e in main () at stacks_eng.c:55 (gdb) f 6

6 0x080484a0 in pop () at stacks_eng.c:14 14 free(arr);


Solution

  • There may be more issues but here is a starter:

    int *arr2 = (int*)malloc(sizeof(int) * size / 2);
    

    This makes the size of arr2 be half of size and then you do:

        for ( i = 0; i < size; i++)
            arr2[i] = arr[i];
    

    So you are clearly writing out of bounds, i.e. undefined behavior.

    Maybe you wanted:

    size /= 2;
    

    before the loop.

    BTW: Check the realloc function. It seems to be what you need. It will perform better and you wont have to write the code to copy elements yourself.