开发者

Find uninitialized variables in C&C++

I really mean C and C++. This project is using a lib in C which is cal开发者_开发问答ling my functions in C++. However the functions are in extern "C" because the lib expects it.

Anyways, in these functions I do new Blah. When a specific function is called (end_tree) i expect all my variables to be initialized. Using Visual Studios, GCC or any other compiler is there a way i can check? I just notice some bools are TRUE which shouldn't be... why, because it wasn't initialized. Is there some kind of _VS_CheckThisMemory(mytree) function or magic I can use?


Don't know it this is what you want but gcc has -Wmaybe-uninitialized and -Wuninitialized. There may be more on the warning options page.


Use valgrind (on linux)

./valgrind myprogram

Especially easy when myprogram was compiled with debug info (gcc -g), but not required. Valgrind will notify where memory is being used that was uninitialzed, and where it was allocated from. If it has debug info, valgrind will report exactly at which file:linenumber things happened. (it can even attach a debugger on the fly for you to insepct things)

It will also detect access beyond allocation boundaries and access after freeing. This is incredibly useful.

Here endeth the useful answer


Edit because it wasn't exactly clear why I was posting the following, as became clear from the comment, let me introduce the remainder of this answer:

When starting to use valgrind with existing codebases, it is almost inevitable that you'll get 'false' positives, i.e. reports that aren't really problems (yet). I include one example of what might trigger such a report, and how you'd typically fix those.

I'm just including this to raise awareness of how to tackle or recognize (semi-)false positives.

Another way of wording it (with reference to Matthieu's convincing reasoning in the comments) is to treat even the 'not-actually-killing' Valgrind warnings as critical: get them fixed, not forgotten.

It is possible that valgrind will report uninitialized access when it is not really a problem. Like, e.g.

 char buf[1024];
 strcpy(buf, "hello");

 char clone[1024];
 memcpy(clone, buf, 1024);

You should fix that by doing something smarter like

 memcpy(clone, buf, strlen(buf));

To make sure there are no uninitialzed 'parts' in buf (or at least not in the area accessed)


Use a self-initializing class to cover those annoying primitives.

template<typename T> class always_initialized {
    T t;
public:
    always_initialized()
        : t(T()) {}
    always_initialized(const T& ref) {
        : t(ref) {}
    operator T&() { return t; }
    operator const T&() const { return t; }
    T& operator=(const T& ref) { return t = ref; }
};


In response to the code linked in the comment, RAIIIA (Resource Acquisition is Initialization In Action (R))

class OtherClass;
class MyClass : public SomeBase {
public:
    // note I got rid of your default constructor, which leaves values unitialized
    MyClass(Var* name, OtherClass* loop)
    :   m_name(name), m_loop(loop) // this right here
    {   }
    virtual ~MyClass(); // no implementation needed here

    void save();

    // made the members protected, other classes have no business accessing them directly
protected:
    Var* m_name;
    OtherClass* m_loop;
};

Your default constructor left the values unitialized, and goes against RAII in its pure form. It's OK to do that, but as you're having problems with uninitialized variables, I would recomment removing default constructors.

EDIT: storing unknown pointers as class members without newing and deleteing them in the class constructor/destructor isn't really RAII, but I hope you do that somewhere.


I solved this by using a solution with templates to act like properties. I used Property like features in C++? but there are other examples for other things like passing in a get/setter.

Essentially generated most of this code bc i was able to and i kept track if a variable was set or not through the property. At the end i just check members and had asserts to tell me if i set a variable or not. I also assert when i 'get' just in case.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜