Common Memory Errors (SOLUTIONS)
Common Memory Errors
Error Types
- A: derefencing a non-pointer
- B: accessing a freed block
- C: freeing a freed block
- D: failing to free memory (memory leak)
- E: no bounds checking (potential buffer overflow)
- F: reading uninitialized memory
- G: referencing nonexistent variable
- H: wrong allocation size
Case 1
char s[8]; int i; gets(s); /* reads "123456789" from stdin */
Error Type | Program Stop Possible? | Fix |
---|---|---|
E, could overflow s |
yes: segmentation fault due to overwritten return address (stack protector/canary value could also be overwritten and halt program) | use fgets |
Case 2
int* foo() { int val = 0; return &val; }
Error Type | Program Stop Possible? | Fix |
---|---|---|
G, after foo returns, val will be deallocated |
no: foo will return normally |
pass in a pointer or use malloc |
Case 3
x = (int *) malloc( N * sizeof(int) ); // manipulate x free(x); ... y = (int *) malloc( M * sizeof(int) ); // manipulate y free(x);
Error Type | Program Stop Possible? | Fix |
---|---|---|
C, x freed twice |
yes: program may halt when double free is detected | probably a typo, should be free(y) |
Case 4
N
andM
are defined elsewhere (#define
)
int **p; p = (int **) malloc( N * sizeof(int) ); for (int i = 0; i < N; i++) { p[i] = (int *) malloc( M * sizeof(int) ); }
Error Type | Program Stop Possible? | Fix |
---|---|---|
H, p points to an array of pointers, but malloc call allocates space for sizeof(int) |
yes: allocated buffer will overflow, segmentation fault possible | should be malloc( N * sizeof(int*) ) |
Case 5
A
is anN
×N
matrix,x
is anN
-sized vector (so the product is a vector of sizeN
)N
is defined elsewhere (#define
)
/* return y = Ax */ int *matvec(int **A, int *x) { int *y = (int *) malloc( N * sizeof(int) ); int i, j; for (i = 0; i < N; i++) for (j = 0; j < N; j++) y[i] += A[i][j] * x[j]; return y; }
Error Type | Program Stop Possible? | Fix |
---|---|---|
F, using += with uninitialized elements of y |
no | use calloc(N, sizeof(int)) to allocate zero-initialized memory |
Case 6
scanf
signature:int scanf(const char *format, ...)
int val; ... scanf("%d", val);
Error Type | Program Stop Possible? | Fix |
---|---|---|
A, scanf takes the location where input will be stored, val treated as a pointer |
yes: segmentation fault likely | should be scanf("%d", &val) |
Case 7
x = (int *) malloc( N * sizeof(int) ); // manipulate x free(x); ... y = (int *) malloc( M * sizeof(int) ); for (i = 0; i < M; i++) y[i] = x[i]++;
Error Type | Program Stop Possible? | Fix |
---|---|---|
B, x accessed after free(x) |
yes: if heap has resized, x may be outside of it and cause a segmentation fault |
free(x) should come later, after final access to x |
Case 8
typedef struct L { int val; struct L *next; } list; void foo() { list *head = (list *) malloc( sizeof(list) ); head->val = 0; head->next = NULL; // create and manipulate the rest of the list ... free(head); return; }
Error Type | Program Stop Possible? | Fix |
---|---|---|
D, nodes after head not freed and reference to them is lost |
no | iterate through the linked list to free each node |