4800
Every programmer has the potential to be a great programmer. Equally, every programmer has the potential to include catastrophic errors, particularly when working under the pressure of internet time. Unfortunately, as we all know, code does not exist, even today, solely in internet time. It must be maintained and improved for months or years after its original creation.
This is particularly true for open-source projects if no one individual has assumed maintenance responsibility for the code. Errors can fester for years in legacy code before becoming apparent simply because no one documented a user behavior assumption or checked memory pointers. When we inspect legacy code for a customer, they are often horrified at the number of defects, including defects they would regard as stop-ship, still present in their applications.
The problems of coding errors are particularly acute in the embedded software universe. The target environment is pretty hostile for testers, with limited target resources (memory, I/O) and the fact that code is often in read-only memory. The choice of debugging aids is limited. Not all operating systems are supported, and there's frequently an unsupportable memory overhead that impacts real-time behavior testing. Nor does the multitude of toolchains help with different chips for different projects and development environments with inconsistent tool support.
The goal of this article is to analyze briefly seven important causes of fatal errors in C and C++ programs, along with tips on avoiding them. These errors can be directly tied to a major percentage of downtime in C and C++ production systems. Research tells us that over 70% of the effort spent on most C and C++ applications is spent in maintenance. We all have much better things to do than maintain broken code. If every programmer reading this article avoids just one of these fatal errors in his or her future code, we could be looking at a significant improvement in the defect density of C and C++ applications.
The seven causes of fatal errors in C and C++ covered in this article are: memory leaks, NULL pointer dereferences, bad deallocations, out-of-bounds array accesses, uninitialized variables, forgetting copy constructors and assignment operators in C++ and order of initialization in C++.
A memory leak is a loss of available memory space. This occurs when dynamic data are no longer needed in the program, but the memory that is used has not been deallocated. It can also occur when an assignment is made to a pointer variable that already holds the address of an allocated area.
Each time a memory leak occurs, the application drains the available memory pool. Even in virtual-memory systems, the gradual increase in application size can result in performance degradation that affects the entire system. Eventually, this performance degradation can lead to a fatal out-of-memory condition that may be encountered by an application unrelated to the one that caused the memory leak in the first place.
Tip: make sure you match allocation calls with deallocation calls when doing unit testing, particularly where there might be an early return from a function where dynamic data was allocated. It's also essential to check, before assigning to a pointer, that the memory accessible via that pointer is freed prior to the assignment or made accessible some other way.
A NULL pointer refers to a specific, invalid memory address. A NULL pointer dereference follows a NULL pointer to that memory location and attempts to access data at an invalid address. A NULL pointer dereference will usually cause a program exception; on systems without memory management hardware, it may not be detected at all. This can cause unpredictable results that are very difficult to trace.
Tip: assume the most unlikely event will occur in all situations and add appropriate error-checking and recovery code; this will usually be in the form of if/else statements around the area of the code that accesses the suspect variables. If you have the time, document every assumption you make right in the code, so those maintaining the code in the future will have a shorter learning curve.
Bad deallocation refers to the use of an inappropriate memory release operation or to the deallocation of memory that was never specifically allocated. The impact of this error type will depend on the compiler and specific operation and can range from no effect at all to unexpected results, a memory leak, memory corruption or a program exception.
Tip: the key to avoiding bad deallocations is to match allocations and deallocations carefully and make sure the deallocation is appropriate for the memory class of the structure that is deallocated. A secondary technique is to check carefully the checking of memory usage during unit testing.
Trending Topics
| You Need A Budget | Feb 10, 2012 |
| The Linux powered LAN Gaming House | Feb 08, 2012 |
| Creating a vDSO: the Colonel's Other Chicken | Feb 06, 2012 |
| Your CMS Is Not Your Web Site | Feb 01, 2012 |
| Casper, the Friendly (and Persistent) Ghost | Jan 31, 2012 |
| Razor-qt 0.4 - Qt based Desktop Environment | Jan 30, 2012 |
- Fun with ethtool
- Parallel Programming with NVIDIA CUDA
- 100% disappointed with the decision to go all digital.
- Readers' Choice Awards 2011
- Linux-Based X Terminals with XDMCP
- Validate an E-Mail Address with PHP, the Right Way
- You Need A Budget
- Why Python?
- The Linux powered LAN Gaming House
- Python for Android





37 min 8 sec ago
5 hours 7 min ago
10 hours 14 min ago
11 hours 14 min ago
20 hours 42 min ago
20 hours 52 min ago
1 day 2 hours ago
1 day 6 hours ago
1 day 7 hours ago
1 day 7 hours ago