C++ runtime bounds checking?


Does anyone know how (or whether it's possible) to perform runtime bounds checking in C++?
I know that if you have:
char ch[8];

then you can perform:
size_t sz = sizeof(ch);

and you can know on runtime what the size of the ch array is. But is there a way to do similar thing on pointers allocated with malloc or free? It will be very useful for debugging / avoiding catasptrophic failure!
Who is Participating?
Sorry, this is a long answer because your question is not simple.

The heap interface obviously must store the size of each block it allocates, but the programmer isn't supposed to know or care about how that size gets stored.  If your code needs to "remember" the size, that's an indication of a design flaw.  You also shouldn't be using malloc/free with C++ because constructors and destructors aren't called, unless you're dealing with memory allocated from C functions or writing optimized libraries.

Nevertheless, buffer overruns need to be detected.  Some runtime libraries, especially using kernel support from UNIX, have a facility for allocating blocks of a slightly larger size than normal for the purpose of detecting buffer overruns.  This can also be done for stack allocation.  Note that UNIX usually detects these things anyway, but GCC offers extra debugging support so that the crash will be more likely to be detected when the problem actually happens.  With Microsoft, I believe there are all kinds of assertions activated in debug mode that can catch these kinds of things.  I suppose the CLR of .NET also has its own solutions for this problem.

I'm lucky enough to work on embedded applications where I have access to the full source code including the heap code, boot code, etc.  This lets me write assertions that assume deatils about what the segment/offset of a heap pointer should look like, whether the stack seems valid in the current context, etc.  Most people aren't so lucky to have such detailed information, but I recommend that you learn whatever you can about your implementation, but try to use your assumptions for debugging purposes and not fancy optimizations.  Portability is important.

This leads me to say, C++ is the best.  You can easily use debug versions of the standard containers such as vector and string that will automatically detect bad insertions, references, and deletions, and when you port your code it won't stop working.  Finally, if you allocate with malloc/free you don't have automatic size information that you get when you create an object with new.  Ponder which of these initializations is best:

Myclass* x = new Myclass(whatever);
Myclass* x = (Myclass*)malloc(sizeof(Myclass));
Myclass* x = (Myclass*)malloc(sizeof(whatever));
Yes, there is a way - use vectors and not arrays; here's why: http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.1
>>But is there a way to do similar thing on pointers allocated with malloc or free?

You can do this by creating a debug version of malloc.

I've created a debug version of malloc that logs this type of information at run time.
See following links:

Complex version:

A more simplified version of above code:

For C Only code:

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Jaime OlivaresSoftware ArchitectCommented:
If you are working in Visual C++, you can use are CArray derived object, like CDWordArray. It wraps a standard C array with bounds checking in debug mode. You can know array size with function GetSize(), and also you can use as a standard array with brackets [].
Also you can create your own array object with those capabilities.
C++ is a basically "unsafe" language, so the answer is in general, NO.  Any language where you can use unset pointers, or increment pointers, or add arbitrary subscripts to any expression, or make arbitrary external definitions, or overflow the basic data types, or call functions with arbitrary method pointers and arguments, is not and cannot be made safe.  No amount of tacked-on stuff can change that.

If you need a really "safe" language, you should look at languages that were designed from the start to be safe against crashes, such as Java, Pascal, or Ada.  Yes, they all have their drawbacks, but if your code jsut HAS to be crash-proof, they're the way to go.

(Of course there's no language that can protect you from LOGIC errors, but at least the above will prevent those mystifying random crashes that unsafe languages are so happy to provide.)

Jaime OlivaresSoftware ArchitectCommented:
The solution is not to change language at the first difficult. C++ is an unsafe language but also a flexible and high performance language. You don't have to stay in "basic types" like a simple array. As I told you, you can use more sophisticated classes.
A similar example: if you want to use dinamic multidimensional arrays, you don't have to change to FORTRAN because C++ don't have a "basic type" with this functionality. You can download a C++ class library with this functionality from the Internet or you can build your own tailored to your needs, let's say, with bounds checking.
I completely agree with jaime_olivares.

Moreover, due to Java limitations, it sometimes requires developers to use C/C++ external code, which then gives you the same C/C++ draw backs.
So Java can still crash using external linked code, and it can crash  (endless-loop) via Java code.

You can easily aviod using dummy pointers in C++ applications by using STL containers and/or smart pointers.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.