1

Currently I have the following code below. char **arr is initially set to NULL. then it stores in words while reading from a file. I just randomly chose a large number like 5000 because I don't understand how to do malloc business properly, even after looking online and trying to learn.

Also, when I try to free char **arr (the last section of my code), sometimes I get segmentation faults, sometimes abort traps, etc. If someone could show me how to do something like this properly that would be highly appreciated! Thanks!

char **arr = NULL 

File *fp = fopen("file.txt", "r")
char string[3000];
char counter = 0; 


//to store
while(fscanf(fp, "%s", string)!=EOF){ 
    arr = realloc(arr, 5000); //arbitrarily used a large number like 5000 
    arr[counter] = malloc(5000); 
    strcpy(arr[counter++], string); 
}

//to free

for(i=0; i<counter; i++){
    free(arr[i])
} 
free(arr); 
Programmer
  • 1,266
  • 5
  • 23
  • 44
  • 1
    Possible duplicate of [How can I get a file's size in C?](https://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c) – C.B. Oct 16 '17 at 12:58
  • Compile with all warnings and debug info: `gcc -Wall -Wextra -g` with [GCC](http://gcc.gnu.org/), then **use the debugger** `gdb` and [valgrind](http://valgrind.org/). Read also documentation of [malloc](http://man7.org/linux/man-pages/man3/malloc.3.html) and related – Basile Starynkevitch Oct 16 '17 at 12:58
  • Please provide some [MCVE] with some explanation. Your fix-my-code question is off-topic – Basile Starynkevitch Oct 16 '17 at 12:59

2 Answers2

4

Don't use arbitrary numbers.

The size argument passed to realloc is the new number of bytes to allocate. In your case it could be (counter + 1) * sizeof(char *) bytes. If the file contains more than around a thousand words then 5000 will not be enough. Not to mention you call realloc to not change the size after the first call.

And don't use arbitrary values for the malloc call either. Either use strlen(string) + 1, or if available then you could use strdup instead.


Lastly, don't reassign back to the variable you pass as pointer to realloc. If realloc fails and returns NULL you will have lost your original pointer.

Instead use a temporary variable that you check before assigning backt o the original pointer variable:

char **temp = realloc(arr, ...);
if (temp == NULL)
{
    // ERRORO: Do something appropriate
}

arr = temp;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

Check the manual of getline(), this function allocate the line for you if the * is NULL. Use this function could be a proper way to do it instead of using strlen and fscanf.