0

This program reads a text file into a string array, line by line. I can't understand the meaning of two lines in the code:

char **words = (char **)malloc(sizeof(char*)*lines_allocated);

...

words = (char **)realloc(words,sizeof(char*)*new_size);
...

Please could you help me understand them?

Community
  • 1
  • 1
Danny
  • 528
  • 1
  • 4
  • 27

3 Answers3

7
char **words = (char **)malloc(sizeof(char*)*lines_allocated);

Allocates lines_allocated pointers. When you use pointer to pointers you need to allocate space for the pointers, and them for each of those pointers you allocate space for you data, in this case, a char *.

words = (char **)realloc(words,sizeof(char*)*new_size);

This changes the size of the buffer, as the number of lines is unknown before you read the file, then you need to increase the number of pointers you allocate.

words points to a block that will store lines_allocated pointers at first moment and then it will be increased to new_size when needed.

In your code you also have a line like this:

/* Allocate space for the next line */
words[i] = malloc(max_line_len);

Which will allocate each string separately.


Also, don't cast the result of malloc:

Community
  • 1
  • 1
Enzo Ferber
  • 3,029
  • 1
  • 14
  • 24
4

The first line allocates a pointer to a pointer to character. A pointer to something in C is equivalent to a pointer to an array of that same something, so this is equivalent to saying that it allocates a pointer to an array of pointers to char.

sizeof(char*) is the size of a pointer, and multiplying it by lines_allocated means that the number of pointers in the allocated array will be lines_allocated.

The second line reallocates the array of pointers so that it may now contain new_size pointers instead of lines_allocated pointers. If new_size is larger, the new pointers will be undefined, and must be initialized before being used.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
4

The first line allocates a chunk of dynamic memory (creates space for an array of pointers to char); the second line resizes that chunk.

A better way to write both lines is

char **words = malloc( sizeof *words * lines_allocated); // no cast, operand of sizeof

char **tmp = realloc( words, sizeof *words * new_size );
if ( tmp )
  words = tmp;

In C, you don't need to cast the result of either call, and it's considered bad practice to do so. Also, note the operand to sizeof; if you ever change the base type of words (from char to wchar_t, for example), you won't have to change the malloc or realloc calls.

realloc will return NULL if it can't extend the buffer, so it's safer to assign the result to a temporary variable first, otherwise you risk losing your reference to that memory, meaning you won't be able to access or release it.

John Bode
  • 119,563
  • 19
  • 122
  • 198