Solved

C++ runtime bounds checking?

Posted on 2004-09-06
8
596 Views
Last Modified: 2008-02-01
Hi

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!
0
Comment
Question by:Indrawati
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 3

Accepted Solution

by:
teratoma earned 125 total points
ID: 11993987
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));
0
 
LVL 4

Expert Comment

by:AssafLavie
ID: 11994154
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
0
 
LVL 30

Expert Comment

by:Axter
ID: 11994410
>>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:
http://code.axter.com/debuglogger.h
http://code.axter.com/debuglogger.cpp

A more simplified version of above code:
http://code.axter.com/debugalloc.h
http://code.axter.com/debugalloc.cpp

For C Only code:
http://code.axter.com/debuglog.h
http://code.axter.com/debuglog.c

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11995454
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.
0
 
LVL 22

Expert Comment

by:grg99
ID: 11995717
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.)



0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11995802
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.
 
0
 
LVL 30

Expert Comment

by:Axter
ID: 11997832
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.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

690 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question