nocturne nocturne - 2 months ago 43
C Question

realloc(): invalid next size (core dumped)

I have a simple function that reallocs buffer every time I want to add one char, It works till I want to realloc 24th time. Then realloc(): invalid next size appears. Here is the code:

char * addDataChunk(char * data,char c)
{
char * p;
if(data==NULL)
{
data=(char*)malloc(sizeof(char)*2);
data[0]=c;
data[1]='\0';
return data;
}
else
{
if(p = (char*)realloc(data,((strlen(data)+1)*sizeof(char))))
{
data = p;
}
else
{
printf("realloc error\n");
}
data[strlen(data)] = c;
data[strlen(data)+1] = '\0';
return data;
}
}


and error:

*** Error in `./bootstrap': realloc(): invalid next size: 0x0000000000b9f2a0 ***
Aborted (core dumped)

Answer

The main error is most likely here:

data[strlen(data)] = c;
data[strlen(data)+1] = '\0';

You first overwrite the null terminator with the character. Then you try to get the length of the string which doesn't have the null terminator anymore, which means you will run over the memory allocated, which means undefined behaviour. Your allocation will result in whatever size. And then you continue.

The reason why it doesn't happen before is most likely because the memory allocated happens to have a null at some point and it stays within reasonable boundaries. But not forever.

The best way would be to keep track of the size and not use the expensive strlen() every time, but if you really must/want to, store the value in a variable first.

size_t pos = strlen(data);
data[pos] = c;
data[pos+1] = '\0';

or even switch them around:

data[strlen(data)+1] = '\0';
data[strlen(data)] = c;

Also you would reallocate the exact same amount of memory since strlen()+1 is the allocated 2 bytes from the beginning (string + null terminator). It should be strlen()+2.

Also as a style issue, sizeof(char) is by definition 1 so you don't need to use it unless you feel it adds something to clarity.