Home > Enterprise >  Freeing memory after allocation error (realloc)
Freeing memory after allocation error (realloc)

Time:10-06

The first if statement below checks if, while adding elements to an array, we've reached the end of the buffer size. If we have, it duplicates the original size.

while (token != NULL) {
    tokens[position] = token;
    position  ;

    if (position >= bufsize) {
      bufsize  = LSH_TOK_BUFSIZE;
      tokens_backup = tokens;
      tokens = realloc(tokens, bufsize * sizeof(char*));
      if (!tokens) {
        free(tokens_backup);
        fprintf(stderr, "lsh: allocation error\n");
        exit(EXIT_FAILURE);
      }
    }

    token = strtok(NULL, LSH_TOK_DELIM);
}

The very last if statement checks for an allocation error, and if that happened, it frees tokens_backup, which points to the original tokens.

Why is tokens_backup needed here?

If there was in fact an allocation error couldn't they simply free the original tokens?

The declaration of both are:

char **tokens = malloc(bufsize * sizeof(char*));
char *token, **tokens_backup;

CodePudding user response:

"If there was in fact an allocation error couldn't they simply free the original tokens?"

No we can't, because we've lost the original tokens

If the allocation in tokens = realloc(tokens, bufsize * sizeof(char*)) fails, tokens will be NULL and the pointer we want to free is lost, so the memory can't be freed anymore. Therefore we need to store the original tokens pointer in tokens_backup so we can free tokens_backup.

CodePudding user response:

Some quotes from the C Standard relative to the function realloc (7.22.3.5 The realloc function)

  1. ...If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged

and

4 The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.

In your code snippet the pointer tokens points to the allocated memory. In this statement

tokens = realloc(tokens, bufsize * sizeof(char*));

if the memory can not be reallocated then the function realloc returns a null pointer that is assigned to the pointer tokens overwriting the previous values stored in the pointer. That is in this case the pointer tokens will be a null pointer and the address of the previously allocated memory will be lost. So you will be unable to free the previously allocated memory. As a result there will be a memory leak because as it is written in the first provided quote the previously allocated memory will not be freed by the function realloc itself.

Having a duplicated pointer before calling the function realloc you can free the previously allocated memory using this duplicated pointer in such a case.

  • Related