简体   繁体   中英

C: Error using malloc and realloc on array of structs

I am trying to dynamically allocate memory for a algorithm on a graph. This is my code broken down to the problem:

typedef struct
{
    int id;
    int color;
} node_t;

unsigned int max_n = 2;
node_t* node_malloc = malloc(sizeof(node_t) * max_n);
node_t* nodes = node_malloc;

if(atoi(left_node) > max_n)
{
    max_n = (size_t) atoi(left_node);
    nodes = realloc(nodes, sizeof(node_t) * max_n);
}

For max_n < 9 the realloc works - when max_n is 9 or greater, "free(): invalid pointer:" is thrown.

free(node_malloc);

When free(node_malloc) is called after a realloc happened it throws "free(): invalid next size (fast)"

Thank you for your answers!

What's happened is that after the realloc call, the pointer value in nodes_malloc is no longer valid. If realloc cannot extend the current buffer in place, it will allocate space for a new buffer, copy the contents of the old buffer to it, and then free the old buffer, which is obviously what happens when you extend by more than 9 elements.

Use nodes as a temporary target of the realloc call - if it's not NULL (meaning the realloc succeeded), assign it back to nodes_malloc :

nodes = realloc( nodes_malloc, sizeof *nodes * max_n );
if ( nodes )
{
  nodes_malloc = nodes;
}
else
{
  // realloc failed
}

You have this:

node_t* node_malloc = malloc(sizeof(node_t) * max_n);
node_t* nodes = node_malloc;

After that, the pointers node_malloc and nodes both point to the very same memory.

But after the first call to realloc that's no longer guaranteed. In fact it's almost certain that nodes will point somewhere else, and the node_malloc pointer will be invalid.

Attempting to free(node_malloc) will then lead to undefined behavior .


On a related issue, you should never assign back to the pointer you pass to realloc . If realloc fails it will return NULL , but the old memory allocation will remain valid. If you reassign back to the same pointer, you loose the original memory and have a memory leak. Always use a temporary variable, and check for failure ( NULL ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM