C++ error I keep making over and over again...

Member
Posts: 321
Joined: 2004.10
Post: #1
Besides just being more careful and attentive, is there any technique that
can safeguard against such programmer error? Here's the fault:

MyType *mT; // error! should be myType *mT = new(MyType);

mT->offset = c.container.startPt.offset;
mT->position = c.container.startpt.position;

The compiler (Codewarrior) happily compiles the above, and invariably I step
through the code in the debugger and the structure is displayed correctly
and all the fields are shown being filled out correctly.

I guess I'm a bit surprised because all I've down is created a pointer to MyType.
So how is the debugger getting anything to fill out and display?

So I guess my question is twofold: how to avoid this and why don't I get more
"failure" upfront?
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
Forgetting to initialize pointers causes me trouble a lot, too. You'll just have to learn to deal with it. Sure, in that simple case, it would be possible for the compiler to give you a warning, but make that an instance variable or a global, and you can imagine how that error would get a whole lot harder for the compiler to detect.

The reason that it doesn't always crash immediately is that the pointer contains whatever value was on the stack when it came into scope. In a lot of cases, you can write to an address in memory without immediately causing a crash. Your pointer just happens to contain a "valid" address a lot of the time.

- Alex Diener
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #3
Well, Codewarrior should complain about "mT not initialized before use", but apart from that, you're toast. It is valid C++ to do that. However, do you really need to allocate it on the heap? If not, you can just go MyType mT; and keep it on the stack. That should avoid the problem, although by side-stepping it.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #4
Forgetting stuff like that probably means that you don't know what you are needing to do. If you are just going to new something then delete it a few lines later, make a temproary instance. You should really be using new to allocate memory and if you don't know that you need to do that, then chances are you don't need to.
Quote this message in a reply
Moderator
Posts: 434
Joined: 2002.09
Post: #5
Try turning compiler warnings up to a higher level (often they default to a fairly high warning level but not the max, 3 instead of 4 for instance.) At the highest level the compiler should warn you if a variable may not be initialized. It will even catch cases like this:
Code:
int *myPtr;
if ( isOption1 ) {
   myPtr = new int(0);
}
else
{
   // ...
}
There is a path in the code that may not initialize the pointer, and even if that path never uses the pointer you should fix the problem because 6 months from now someone may add new code.

You will probably get lots of other warnings as well. The goal is to compile without any warnings. This may mean adding explicit type coercions, or other code just to keep the compiler happy. For example if you are assigning a long to a short int, even if you know that the number will never go higher than 10, make the types match, or coerce and maybe add a comment explaining why the coercion is safe, or check the value before coercing it and log an error if it is out of range.

After years of programming on large-scale projects you will find it very difficult to declare something without making sure it is initialized. It becomes second nature. But, it is better to make the compiler find as many troublespots as possible. It's much less expensive than finding problems during testing.

Another coping strategy is scope control. In the example above if you move the pointer declaration code into the if-statement where it is actually used, then if someone tries to use it in a place where it is not initialized, the variable won't even be defined.
Code:
if ( isOption1 ) {
   int *myPtr = new int(0);
   // ...
}
else
{
   // ...
}

Measure twice, cut once, curse three or four times.
Quote this message in a reply
Post Reply