I want to read several files and add lines of text to the content. I would like to save the new changed content in a buffer. The files can be from 0 bytes to 16 MB in size. By adding the lines of text, the file can also be much larger, depending on the content.
At the beginning, I reserve 512 bytes of memory with calloc.
wchar_t *buffer = (wchar_t*)calloc(512, sizeof(wchar_t));
Whenever adding text to memory, I check if the size of the reserved memory is still sufficient with the function realloc. This works quite reliably for small files only with larger files the program crashes. Debbug is unfortunately not possible because of the constellation.
Now my question. If I extend the memory repeatedly with realloc but it fails, is the if statement with buffer == NULL correct? The buffer can theoretically not be zero, since it was already filled before.
How can I catch the error cleanly or fix it?
size_t memoryallocated = 512;
wchar_t *buffer = (wchar_t*)calloc(memoryallocated , sizeof(wchar_t));
while (memoryuse + contenlength >= memoryallocated)
{
memoryallocated *= 2;
buffer = (wchar_t *)realloc(buffer, memoryallocated* sizeof(wchar_t));
if ((buffer == NULL))
{
return NULL;
}
}
wmemcpy(buffer + memoryuse, contentbuf,contenlength);
memoryuse += contenlength; // thx @pm100
return buffer;
If you read the documentation for realloc
, you can see that function returns NULL
if it cannot resize your buffer (due to lack of memory or any other reason). It does not return the old pointer.
So comparing the returned value with NULL
is absolutely correct.
Aside from that you should never do
buffer = realloc(buffer, ...);
Because if realloc
returns NULL
you have lost the old pointer which was not freed (realloc
does not free if it cannot reallocate). This will result in a memory leak.
You should always do -
void * new_ptr = realloc(buffer, new_size); // new_size > 0
if (new_ptr == NULL) {
// Handle error and keep using buffer
} else {
buffer = new_ptr;
}