Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

The pointer argument to the free or realloc function does not match a pointer earlier returned by a memory management function, or the space has been deallocated by a call to free or realloc.

See also undefined behavior 179.

Freeing memory that is not allocated dynamically can result in heap corruption and other serious errors. Do not call free() on anything a pointer other than a pointer one returned by a dynamic standard memory allocation function, such as malloc(), calloc(), realloc(), or aligned_alloc().

A similar situation arises when realloc() is supplied a pointer to non-dynamically allocated memory. The realloc() function is used to resize a block of dynamic memory. If realloc() is supplied a pointer to memory not allocated by a standard memory allocation function, such as malloc(), the behavior is undefined. One consequence is that the program may terminate abnormally.

This rule does not apply to null pointers. The C Standard guarantees that if free() is passed a null pointer, no action occurs.

...

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
 
enum { MAX_ALLOCATION = 1000 };

int main(int argc, const char *argv[]) {
  char *c_str = NULL;
  size_t len;

  if (argc == 2) {
    len = strlen(argv[1]) + 1;
    if (len > MAX_ALLOCATION) {
      /* Handle error */
    }
    c_str = (char *)malloc(len);
    if (c_str == NULL) {
      /* Handle error */
    }
    strcpy(c_str, argv[1]);
  } else {
    printf("%s\n", "usage: $>a.exe [string]");
    return -1EXIT_FAILURE;
  }
  free(c_str);
  return 0;
}

...

Code Block
bgColor#FFcccc
langc
#include <stdlib.h>
 
enum { BUFSIZE = 256 };
 
void f(void) {
  char buf[BUFSIZE];
  char *p = (char *)realloc(buf, 2 * BUFSIZE);
  if (p == NULL) {
    /* handleHandle error */
  }
}

Compliant Solution (realloc())

...

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
 
enum { BUFSIZE = 256 };
 
void f(void) {
  char *buf = (char *)malloc(BUFSIZE * sizeof(char));
  char *p = (char *)realloc(buf, 2 * BUFSIZE);
  if (p == NULL) {
    /* handleHandle error */
  }
}

Note that realloc() will behave properly even if malloc() failed, because when given a null pointer, realloc() behaves like a call to malloc().

...

Bibliography

...

[ISO/IEC 9899:2011]Annex J, subclause J.2, "Undefined Behavior"
[Seacord 2013b]Chapter 4, "Dynamic Memory Management"

 

...