Dealing with uninitalized memory
Friday, June 18, 2010 | Permalink
A common source of undeterministic bugs that are hard to find is uninitialized variables. In a local scope this is typically detected by the compiler, but for member variables in a class you're typically on your own. You forget to initialize a bool and in 255 cases of 256 you get 'true', so the code might appear to work if that's a reasonable initial value. Until your bool ends up on a memory address with a zero in that byte.
One way to deal with this problem is to simply initialize all memory to zero first thing in the constructor. Unfortunately, that adds a runtime cost and code size cost. I figured someone must have attacked this problem before, and I'm sure someone did, but googling on it I haven't found much about it. So I came up with my own approach, which I'll be adding to Framework4. Basically it's a small class and a set of macros to simplify stuff. In my class definition I just tag the range of variables I want to check, typically all of them.
class MyClass
{
public:
MyClass();
...
private:
CLASS_BEGIN()
// Variables go here
CLASS_END()
};
This inserts a start and end tag into the class, which are basically two uint32.
In the constructor I do this:
MyClass::MyClass() : CLASS_INIT()
{
...
}
CLASS_INIT() will initialize all memory between the tags to 0xBAADCODE, before any other initialization happens.
At some point where I expect everything to be set up, for instance the end of the constructor or maybe after some call to Init() or whatever, I simply add CLASS_VERIFY() which will check that no memory is left as 0xBAADCODE. Also, it will check start and end tags to make sure they have not been touched, which will also detect common out of range writes.
Adding this to my simple test app I found a whole bunch of variables I didn't initialize. Most of them were simply unused though. I can't imagine what kind of bug could be avoided if something like this is added to the main system classes in a big scale project. And the best of all, this come at no extra cost at runtime because in final builds those macros are defined to nothing.
[
21 comments |
Last comment by niko (2010-11-12 03:00:35) ]