Online Book Reader

Home Category

Professional C__ - Marc Gregoire [465]

By Root 1441 0
crashes. However, they don’t always do so. They can instead lead to subtle errors, in which the program does not terminate but instead produces erroneous results. Erroneous results can lead to serious consequences, for example when external devices (such as robotic arms, X-ray machines, radiation treatments, life support systems, etc.) are being controlled by the computer.

Note that the discussed symptoms for memory freeing errors and memory access errors are the default symptoms for release builds of your program. Debug builds will most likely behave differently, and when run inside a debugger, the debugger might break into the code when an error occurs.

Tips for Debugging Memory Errors

Memory-related bugs often show up in slightly different places in the code each time you run the program. This is usually the case with heap memory corruption. Heap memory corruption is like a time bomb, ready to explode at some attempt to allocate, free, or use memory on the heap. So, when you see a bug that is reproducible, but shows up in slightly different places, suspect memory corruption.

If you suspect a memory bug, your best option is to use a memory-checking tool for C++. Debuggers often provide options to run the program while checking for memory errors. Additionally, there are some excellent third-party tools such as purify from Rational Software (now owned by IBM) or valgrind for Linux (discussed in Chapter 21). Microsoft provides a free download called Application Verifier which can be used in a Windows environment. It is a run-time verification tool to help you in finding subtle programming errors like the previously discussed memory errors. These debuggers and tools work by interposing their own memory allocation and freeing routines in order to check for any misuse of dynamic memory, such as freeing unallocated memory, dereferencing unallocated memory, or writing off the end of an array.

If you don’t have a memory-checking tool at your disposal, and the normal strategies for debugging are not helping, you may need to resort to code inspection. Here are some specific items to look for, once you’ve narrowed down the part of the code containing the bug.

Object and Class-related Errors

Verify that your classes with dynamically allocated memory have destructors that free exactly the memory that’s allocated in the object: no more, and no less.

Ensure that your classes handle copying and assignment correctly with copy constructors and assignment operators, as described in Chapter 7.

Check for suspicious casts. If you are casting a pointer to an object from one type to another, make sure that it’s valid. When possible, use dynamic_casts.

General Memory Errors

Make sure that every call to new is matched with exactly one call to delete. Similarly, every call to malloc, alloc, or calloc should be matched with one call to free. And every call to new[] should be matched with one call to delete[]. To avoid double freeing memory or using freed memory, it’s recommended to set your pointer to nullptr after freeing its memory.

Check for buffer overruns. Anytime you iterate over an array or write into or read from a C-style string, verify that you are not accessing memory past the end of the array. These problems can often be avoided by using STL containers and strings.

Check for dereferencing of invalid pointers.

When declaring a pointer on the stack, make sure you always initialize it as part of its declaration, for example: T* p = nullptr;

or

T* p = new T;

but never:

T* p;

Similarly, make sure your classes always initialize pointer data members in their constructors, by either allocating memory in the constructor or setting the pointers to nullptr.

Debugging Multithreaded Programs

C++11 includes a threading library that provides mechanisms for threading and synchronization between threads. This threading library is discussed in Chapter 22. Multithreaded C++ programs are common, so it is important to think about the special issues involved in debugging a multithreaded program. Bugs in multithreaded programs

Return Main Page Previous Page Next Page

®Online Book Reader