Avoiding null pointer exceptions in a large C ++ code base

I have inherited a large C ++ database, and I have the task of avoiding null pointer exceptions that may occur in the code base. Are there any static analysis tools, I think you used successfully.

What other things are you looking for?

+4
source share
6 answers

You can start by eliminating NULL sources:

Edit

if (error) { return NULL; } 

IN

 if (error) { return DefaultObject; // Ex: an empty vector } 

If the returned objects are not applied by default, and your code base already uses exceptions, do

 if (error) { throw BadThingHappenedException; } 

Then add the treatment to the appropriate places.

If you work with legacy code, you can make some shell functions / classes:

 ResultType *new_function() { ResultType *result = legacy_function(); if (result) { return result; } else { throw BadThingHappenedException; } } 

New functions should start using new functions and have proper exception handling.

I know that some programmers just don't get exceptions, including smart people like Joel . But what ends up returning NULL is that this NULL goes crazy, as everyone just thinks that it is not their business to deal with this and return silently. Some functions may return an error code, which is good, but the caller often finishes returning still-more-NULL in response to errors. Then you see a lot of NULL checks in each individual function, no matter how trivial the function is. And all that is required is just one place that does not verify that NULL crashes into the program. Exceptions make you think carefully about the error and decide exactly where and how to handle it.

It seems you are just looking for simple solutions like static analysis tools (which you should always use). Changing link pointers is also a great solution. However, C ++ has the beauty of RAII, which eliminates the need for "try {} finally {}" everywhere, so I think it's worth your serious consideration.

+5
source

If you basically maintain a basic code base, one of the lowest levels of effort and the highest results you can do is start refactoring your bare pointers to links to counted pointers .

I would also look at something like Purify , which will help your code detect memory corruption.

+2
source

First, as a technical issue, C ++ has no NULL pointer exceptions. NULL pointer allocation has undefined behavior, and on most systems the program abruptly interrupts ("crash").

Regarding tools, I also recommend the question:

Should I use tools for analyzing static code in C ++?

Regarding markup of NULL pointers in particular, consider that dereferencing a NULL pointer has three main elements:

  • Entering a NULL pointer.
  • Thread this pointer elsewhere in the program.
  • A variation of this pointer.

The hard part for the static analysis tool is, of course, step 2, and the tools differ in how complicated the path is, which they can accurately (i.e. not too many false positives). It might be helpful to see some specific examples of errors that you want to catch in order to better advise which tool will be most effective.

Disclaimer: I work for Coverity.

+2
source

If you do not want to change any code, you need to use some tools (see other answers). But for the special part of the problem (where you put the pointer in the function to use it) there is a small little Macro definition that you can use to find some little Buggers: (no time in release mode and adds a visible condition to the code)

  #ifdef NDEBUG #define NotNull(X) X #else // in Debug-Mode template<typename T> class NotNull; template<typename T> // template specialization only for pointer-types class NotNull<T*> { public: NotNull(T* object) : _object(object) { assert(object); } operator T*() const { return _object; } T* operator->() const { return _object; } private: T *_object; }; #define NotNull(X) NotNull<X> #endif // in Debug-Mode 

You just change each function:

 void increase(int* counter) { .. } 

to that

 void increase(NotNull(int*) counter) { .. } 

ps: first found HERE and can be even more optimized

+2
source

The question related to the question is the purpose of avoiding this, because they do not want the client to see a collapse? In many cases, null pointers are unexpected conditions that should be processed immediately, but too often they are passed through the system like hot potatoes.

I once worked on a code base where the habit was at the entrance to the function to first check for null pointers, and if so, return it. The problem with this is that the tool is not crashing, it ultimately generated bad data silently. And trying to debug these problems was difficult, because for a long time through many functions before the results became intolerable or eventually had to appear, null pointers might have been illegally started.

Ideally, you need the right statements, at least during your development period, so consider a macro to hide or override the statement for production assemblies

+1
source

All Articles