Reputation: 185
Update: Per the feedback below which I thought I understood, I've amended the code as follows but it is still troublesome:
unsigned int count = 0;
char* filebuffer;
filebuffer = malloc(sizeof(char));
if (!filebuffer)
{
error(500);
return false;
}
while (fread(filebuffer, sizeof(char), 1, file) == 1)
{
count++;
filebuffer = realloc(filebuffer, count * sizeof(char));
printf("%lu\n", (count + 1) * sizeof(char));
}
if (feof(file))
{
*content = filebuffer;
*length = count;
}
Below is some code which is meant to go through a file which is piped through to the function by popen (it's a php file), and store it into a buffer, and then give content* the same pointer and *length the number of bytes read.
However it's not working. Valgrind says:
==7608== Conditional jump or move depends on uninitialised value(s)
==7608== at 0x4C31FCE: strstr (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7608== by 0x4036C0: interpret (server.c:513)
==7608== by 0x401D66: main (server.c:259)
==7608== Uninitialised value was created by a heap allocation
==7608== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7608== by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7608== by 0x40418C: load (server.c:662)
==7608== by 0x403672: interpret (server.c:502)
==7608== by 0x401D66: main (server.c:259)
The code is:
unsigned int count = 0;
char* filebuffer;
filebuffer = malloc(sizeof(char));
if (!filebuffer)
{
printf("oh noes\n");
error(500);
return false;
}
while (fread(filebuffer, sizeof(char), 1, file) == 1)
{
count++;
filebuffer = realloc(NULL, sizeof(filebuffer) + sizeof(char));
}
if (feof(file))
{
*content = filebuffer;
*length = count;
}
Any feedback welcome and thanks in advance.
Upvotes: 2
Views: 146
Reputation: 206717
The argument to realloc
is wrong.
sizeof(filebuffer)
is equal to sizeof(char*)
. It does not evaluate to the the size of the array allocated.
You need to keep track of the size using another variable and use that variable. count
seems to be that variable but it's not clear from your code what you are doing and what those variables stand for.
Also, when you use
filebuffer = realloc(NULL, some_size);
it is equivalent to
filebuffer = malloc(some_size);
which leads to a lot of leaked memory. To stop the memory leaks, you need to use
filebuffer = realloc(filebuffer, some_size);
Upvotes: 2
Reputation: 13846
Your realloc
does not take the buffer of previously allocated one, also you need to track the the size of the buffer.
filebuffer = realloc(NULL, sizeof(filebuffer) + sizeof(char));
It should be
filebuffer = realloc(filebuffer, <the new size>);
But filebuffer = malloc(sizeof(char));
is just looks as bad as it is, you are allocating ONE byte each type. If you don't know the size of the file in advance, I suggest you allocate block by block.
#define BLOCKSIZE 1024
char* filebuffer;
size_t current;
filebuffer = malloc(BLOCKSIZE);
current = BLOCKSIZE;
// in the loop
filebuffer = realloc(filebuffer, BLOCKSIZE + current);
current = BLOCKSIZE + current;
Upvotes: 0