Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added an improved example moved over from MEM08-C

...

This code example now reliably outputs "2222 2222."

Noncompliant Code Example

In this example, a gadget object is allocated, then realloc() is called to create a widget object using the memory from the gadget object.  While reusing memory to change types is acceptable, accessing the memory copied from the original object is undefined behavior.

Code Block
bgColor#FFCCCC
langc
#include <stdlib.h>
 
typedef struct gadget gadget;
struct gadget {
  int i;
  double d;
  char *p;
};
 
typedef struct widget widget;
struct widget {
  char *q;
  int j;
  double e;
};
 
gadget *gp;
widget *wp;
 
/* ... */
 
wp = (widget *)realloc(gp, sizeof(widget));
if (wp->j = 12) {
  /* ... */
}

Compliant Solution

This compliant solution reuses the memory from the gadget object, but re-initializes the memory to a consistent state before reading from it.

Code Block
bgColor#ccccff
langc
 
#include <stdlib.h>
 
typedef struct gadget gadget;
struct gadget {
  int i;
  double d;
  char *p;
};
 
typedef struct widget widget;
struct widget {
  char *q;
  int j;
  double e;
};
 
gadget *gp;
widget *wp;
 
/* ... */
 
wp = (widget *)realloc(gp, sizeof(widget));
memset(wp, 0, sizeof(widget));
/* ... */
if (wp->j = 12) {
  /* ... */
}

Risk Assessment

Optimizing for performance can lead to aliasing errors that can be quite difficult to detect. Furthermore, as in the preceding example, unexpected results can lead to buffer overflow attacks and/or bypassing security checks and/or unexpected execution.

...

[Acton 2006]"Understanding Strict Aliasing"
GCC Known Bugs"C Bugs, Aliasing Issues while Casting to Incompatible Types"
GCC Manual 
[ISO/IEC 9899:2011]Section 6.5, "Expressions"
[Walfridsson 2003]Aliasing, Pointer Casts and GCC 3.3

 

...