...
Reading a pointer to deallocated memory is undefined behavior because the pointer value is indeterminate and can have a trap representation. In the latter case, doing so may cause a hardware trap.
...
Code Block |
---|
|
#include <stdlib.h>
struct node {
int value;
struct node *next;
};
void free_list(struct node *head) {
for (struct node *p = head; p != NULL; p = p->next) {
free(p);
}
} |
...
Code Block |
---|
|
#include <stdlib.h>
struct node {
int value;
struct node *next;
};
void free_list(struct node *head) {
struct node *q;
for (struct node *p = head; p != NULL; p = q) {
q = p->next;
free(p);
}
} |
...
Code Block |
---|
|
#include <stdlib.h>
#include <string.h>
enum { BUFFERSIZE = 32 };
int main(int argc, const char *argv[]) {int main(int argc, char *argv[]) {
if (argc < 2) {
/* Print usage */
return EXIT_FAILURE;
}
char *return_val = 0;
const size_t bufsize = strlen(argv[1]) + 1;
char *buffbuf = (char *)malloc(BUFFERSIZEbufsize);
if (!buffbuf) {
return EXIT_FAILURE;
}
/* Handle error... */
}
free(buffbuf);
if (argc > 1) {/* ... */
return_val = strncpy(buffbuf, argv[1], BUFFERSIZE - 1)bufsize); // Undefined behavior
if (return_val) {
return EXIT_FAILURE;
}
return 0EXIT_SUCCESS;
}
|
Compliant Solution
In this compliant solution, the memory is freed after its final use, and the pointer is zeroed in compliance with MEM01-C. Store a new value in pointers immediately after free():
Code Block |
---|
|
#include <stdlib.h>
#include <string.h>
enum { BUFFERSIZE = 32 };
int main(int argc, const char *argv[]) {
int main(int argc, char *argv[]) {
if (argc < 2) {
/* Print usage */
return EXIT_FAILURE;
}
char *return_val = 0;
const size_t bufsize = strlen(argv[1]) + 1;
char *buffbuf = (char *)malloc(BUFFERSIZEbufsize);
if (!buffbuf) {
/* Handle error */return EXIT_FAILURE;
}
if (argc > 1){/* ... */
return_val = strncpy(buffbuf, argv[1], bufsize);
BUFFERSIZE - 1);if (return_val) {
}
free(buffbuf);
buff = 0;
return EXIT_FAILURE;
}
/* ... */
free(buf);
return 0EXIT_SUCCESS;
}
|
Noncompliant Code Example
...