Skip to content
Physics and Astronomy
Home Our Teaching Resources C programming Common mistakes
Back to top
On this page
Contents

Common mistakes with memory allocation

Dereferencing a pointer without allocating some memory for it

This is the ultimate memrory allocation error and will lead to disaster.

Bad Good
  double *p;
  int n = 8;

  for(int i = 0; i < n; ++i )
    p[i] = i*2; // Disaster!

  double *p;
  int n = 8;

  p = xmalloc(n*sizeof *p);
  for(int i = 0; i < n; ++i )
    p[i] = i*2; // Now OK

Not checking for NULL return from malloc()

Bad Good
  double *p;
  int n = 8;

  p = malloc(n*sizeof *p);
  for(int i = 0; i < n; ++i )
    p[i] = i*2;

  double *p;
  int n = 8;

  p = malloc(n*sizeof *p);
  if ( p == NULL ) {
    fprintf(stderr, "Out of memory!\n");
    exit(1);
  }

  for(int i = 0; i < n; ++i )
    p[i] = i*2;

Better
void *xmalloc(size_t n) {
  void *p = malloc(n);
  if (p == NULL) {
    fprintf(stderr, "Out of memory!\n");
    exit(1);
  }
  return p;
}

void anotherfunction(void) {
  double *p;
  int n = 8;

  p = xmalloc(n*sizeof *p);
  for(int i = 0; i < n; ++i )
    p[i] = i*2;

  // ...
}

Using malloc() instead of an ordinary array when the array is not needed after the function returns

  • Ordinary array declaration is fast and the memory is automatically released when the function returns.
  • Dynamic memory allocation is slow and is permenant until freed.

So:

  • Use normal arrays when the array is not needed after the function returns.
  • Use dynamic allocation when it is.
Poor Better
#include <stdlib.h>

void poorfun(int n) {
  double *x;

  x = xmalloc(n * sizeof *x);
  // .. Do some stuff with x

  free(x);
}

void betterfun(int n) {
  double x[n];

  // .. Do some stuff with x
}

The first version has more ways to go wrong, we might forget to call free(), and is also slower. (However, until C99 programmers had no choice as array sizes had to be declared at compile time.) It's not unknown for the speed of some programs to be dominated by calls to malloc().

Using an ordinary array instead of malloc() when the array is needed after the function returns

This is the reverse of the previous one but is much more serious as the program will give the wrong answers or crash.

Bad Better
int **badnew2dint(int m, int n) {
  int *p[m];
  int i;

  for (i = 0; i < m; ++i)
    p[i] = malloc(n * sizeof *p[i]);
  return p; // p vanishes!
}

// Allocate a 2-D array of ints
int **new2dint(int m, int n) {
  int **p;
  int i;

  p = xmalloc(m * sizeof *p);
  for (i = 0; i < m; ++i)
    p[i] = malloc(n * sizeof *p[i]);
  return p;
}

                                                                                                                                                                                                                                                                       

Validate   Link-check © Copyright & disclaimer Privacy & cookies Share
Back to top