Versions Compared

Key

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

...

Non-compliant Code Example 1

The function build_list is a simple function to create a singly-linked list. The nodes in the linked list are defined as:

Code Block

struct int_list {
  struct int_list *next;
  int payload;
};

There is an integer payload and a pointer to the next node in the list. In build list, the nodes are allocated and added to the list. The pointer temp is used as a place holder to allocate and set up the node before it is added to the list. However, temp is prematurely freed, in effect de-allocating the list immediately after allocation. When the build_list function returns, list->next refers to freed memory resulting in an error.

Code Block

/*
 *  list points to the pre-allocated base node in the list
 */
void build_list(struct int_list *list, size_t size) {
  size_t i;
  struct int_list *c_ptr = NULL;
  list->payload = 42;
  c_ptr = list;

  for (i=0; i < size; i++) {
    struct int_list *temp=malloc(sizeof(struct int_list));
    temp->payload = c_ptr->payload+1;
    c_ptr->next = temp;
    c_ptr = c_ptr->next;
    free(temp);         /* error */
  }
  c_ptr->next = NULL;
}

Compliant Solution 1

Free the memory only when it can be guaranteed that it is no longer used. In the above example this can be done by removing the call to free(temp) in buld_list.

This example Kerrington 88 shows items being deleted from a linked list. However, p is freed before the p->next is executed. Thus, when p->next is executed, p will refer to freed memory.

Code Block

for(p = head; p != NULL; p= p->next)

Compliant Solution 1

To correct this error, a reference to p->next is stored in q before freeing p.

Code Block

for (p = head; p != NULL; p= p->q) {
  q = p->next;
  free(p)
Code Block

struct int_list {
  struct int_list *next;
  int payload;
};

 build_list(const struct int_list *list) {
  int i;
  struct int_list *list = malloc(sizeof(struct int_list));

  struct int_list *c_ptr = NULL;
  struct int_list *temp = NULL;
  list->payload = 42;
  c_ptr = list;

  for (i=0; i < 10; i++) {
    temp = malloc(sizeof(struct int_list));

    temp->payload = c_ptr->payload+1;
    c_ptr->next = temp;
    c_ptr = c_ptr->next;
  }
  temp = NULL;
  c_ptr->next = NULL;
}

References

VU#390044, http://www.kb.cert.org/vuls/id/390044