...
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