Troubleshooting C/C++ Memory Related Crashes

The following is a reformatted excerpt of a very helpful article from 2006 by Rakesh Shrestha about writing crash-proof programs.

Causes of Crashes

Accessing or deleting memory you do not own

Uncaught exceptions

  1. Dereferencing a NULL pointer
    1. *(NULL)
    2. NULL->member
    3. NULL[1]
    4. NULL->function()
    5. strcpy( NULL, "hello" )
    6. *(NULL)(params);
    7. this == NULL during an implicit (*this).
  2. Dereferencing an uninitialized pointer
    1. blah* pPointer; *pPointer
    2. All same cases as (1)
  3. Dereferencing a deleted pointer
    1. delete pPointer; *pPointer
    2. All same cases as (1)
  4. Deleting an uninitialized pointer
    1. blah* pPointer; delete pPointer;
  5. Deleting a pointer twice
    1. delete pPointer; delete pPointer;
  6. Deleting non-dynamic memory
    1. int x; int* p = &x; delete p;
  7. Writing beyond the bounds of an array
    1. int x[10]; x[-1] = 1;
    2. int x[10]; x[10] = 1;
    3. (a) and (b) but hidden in loops
  1. Divide by zero
    1. int x = 0; 2/x
    2. double x = 0.0; 2.0/x
    3. int x = 0; 2%x
    4. You will also see overflow and underflow occasionally
  2. Stack overflow
    1. Infinitely recursive function
      void InfiniteRecurse( int x ) {
          if ( false ) {
              // terminating condition which is never met
              return;
          }
          else {
              // recurse condition which is always met
              InifiniteRecurse(x+1);
          }
      }
    2. Infinitely recursive set of functions
      Same as (a) but a set of functions are mutually recursive, so the call stack looks like a -> b -> c -> a -> b -> c -> a -> b -> c -> a -> b -> c -> ...
    3. Valid recursive function but each call using too much stack space
      void BigRecurse( unsigned int x ) {
          int aBigArray[1000];
          if( x >= 1000 ) {
              return;
          }
          else {
              aBigArray[x] = x;
              BigRecurse(x+1);
          }
      }
  3. Out of memory; this may show up as an exception on some systems, others will just return NULL from the new or malloc (Visual C++’s C library returns NULL and does not throw an exception).
    1. int* p = new int;
  4. User or library code generated exceptions that failed to get wrapped in a try/catch. Third party code may throw exceptions under some circumstances. Your code might intentionally throw exceptions. If these miss getting caught then the exceptions will make it all the way to the top of the thread.
    1. ret = ThisFunctionThrowsAnException();