Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Pointer being freed was not allocated." error after malloc, realloc

I have this error with the following code:

int main(){
    point   *points = malloc(sizeof(point));
    if (points == NULL){
        printf("Memory allocation failed.\n");
        return 1;
    }
    other_stuff(points);
    free(points);
    return 0;
}
void other_stuff(point points[]){
    //stuff
    realloc(points, number*sizeof(point))
}

I have searched, but found only examples where it was clear there was no allocation.

Here, I used malloc to initialise points, and later changed its size with realloc; so how is the pointer "not allocated" when I come to free it?

like image 377
OJFord Avatar asked Dec 14 '13 00:12

OJFord


People also ask

What does pointer being freed was not allocated?

Your code doesn't allocate any memory for the string. It simply copies a string from one string to the memory used by another (a string of spaces).

How can I free space after malloc?

When you no longer need a block that you got with malloc , use the function free to make the block available to be allocated again. The prototype for this function is in stdlib. h .

Does realloc need to be freed?

Once you call realloc() , you do not have to free() the memory addressed by pointer passed to realloc() - you have to free() the memory addressed by the pointer realloc() returns. (Unless realloc() returns NULL , in which case the original block of memory - passed to realloc() - has to be free() 'd.)

Does malloc need to be freed?

But the memory allocation using malloc() is not de-allocated on its own. So, “free()” method is used to de-allocate the memory. But the free() method is not compulsory to use.


2 Answers

realloc may move the memory to a new location (if there is not enough space to expand the old pointer). If that happens, you need to free the new pointer.

Try this tweak:

int main(){
    point   *points = malloc(sizeof(point));
    if (points == NULL){
        printf("Memory allocation failed.\n");
        return 1;
    }
    other_stuff(&points);
    free(points);
    return 0;
}
void other_stuff(point **points){
    //stuff
    point *temp = realloc(*points, number*sizeof(point));
    if(temp != NULL) {
      *points = temp;
      // and do your stuff
    }
    else {
      // panic? memory reallocation failed. Deal with it gracefully.
    }
}

By passing a handle to other_stuff, we give it control not only over the place where the pointer is pointing, but to the address of the pointer itself. This allows it to move the memory around. Handles are a good way to manage memory dynamically; but conceptually a pointer to a pointer takes some getting used to...

like image 116
Floris Avatar answered Nov 03 '22 01:11

Floris


realloc returns a new pointer. That is what you need to free (eventually) if the function succeeded. Otherwise, it failed, and you keep the old pointer around for this case.

How to use realloc:

whataver *f = malloc(count * sizeof(*f));
/* ... */
whatever *temp = realloc(f, new_count * sizeof(*temp));
if (temp)
    f = temp;  // realloc worked, f is no longer valid/needed
else
    free(f);   // error

realloc may return the same pointer, or it may not. The point is that you no longer care about the original pointer if realloc succeeded. If it had to allocate a new block then the original pointer is invalid. If it didn't then it returned the same pointer, and you certainly don't want to deallocate that right away.

like image 36
Ed S. Avatar answered Nov 03 '22 01:11

Ed S.