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 and M 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 an N × N matrix, x is an N-sized vector (so the product is a vector of size N)
  • 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