So, I am trying to copy char per char of a file in a chunk of memory that expands accordingly with the file's size... At the end the code print all ok, but if I use valgrind it will run forever.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
FILE *dict = fopen("dictionaries/large", "r");
if (dict == NULL)
{
printf("Could not load the file\n");
return 1;
}
// Buffer to read data.
char *buffer = malloc(1);
if (buffer == NULL)
{
return 1;
}
char *word = malloc(1);
if (word == NULL)
{
return 1;
}
int i = 0;
// Load file byte per byte. Copy char per char.
while (fread(buffer, 1, 1, dict))
{
word[i] = buffer[0];
i++;
char *tmp = realloc(word, i + 1);
word = tmp;
}
printf("%s\n", word);
fclose(dict);
free(buffer);
free(word);
}
I tried to create a temporary pointer after realloc and then assign the new pointer to the old one, but it didn't work as realloc can return a pointer to another address.
It is always easier to divide program into logical bits and place them in functions.
char *addToBuff(char *buff, int ch, size_t *size)
{
//working on local variable buff. No need for a temporary variable
buff = realloc(buff, *size + 1);
if(buff)
{
buff[*size] = ch;
*size += 1;
}
return buff;
}
char *readToBuff(FILE *fi, size_t *size)
{
char *buff = NULL;
int ch;
*size = 0;
while((ch = fgetc(fi)) != EOF)
{
//to avoid memory leak - temporary variable needed
char *tmp = addToBuff(buff, ch, size);
if(!tmp) {/* handle allocation error */}
else buff = tmp;
}
return buff;
}
int main(void)
{
size_t size = 0;
char *buff = readToBuff(stdin, &size);
printf("read %zu chars. Buff address: '%p'\n", size, (void*)buff);
free(buff);
}