在C& C ++中查找未初始化的变量

时间:2011-05-07 13:44:43

标签: c++ c

我的意思是C和C ++。这个项目在C中使用了一个lib,它在C ++中调用我的函数。但是这些函数在extern“C”中,因为lib期望它。

无论如何,在这些功能中我做new Blah。当调用特定函数(end_tree)时,我希望我的所有变量都被初始化。使用Visual Studios,GCC或任何其他编译器有一种方法可以检查吗?我只是注意到一些bool是真的,不应该......为什么,因为它没有被初始化。我可以使用某种_VS_CheckThisMemory(mytree)函数或魔法吗?

5 个答案:

答案 0 :(得分:3)

不知道这是你想要的,但gcc-Wmaybe-uninitialized-Wuninitializedthe warning options page上可能会有更多内容。

答案 1 :(得分:3)

使用valgrind(在linux上)

./valgrind myprogram

使用调试信息(gcc -g)编译myprogram时非常容易,但不是必需的。 Valgrind将通知未使用的内存使用位置以及从中分配的位置。如果它有调试信息,valgrind将准确报告哪个文件:发生了事情。 (它甚至可以动态附加一个调试器,让你可以看到事情

它还将检测超出分配边界的访问权限以及释放后的访问权限。这非常有用。

这里有用的答案


编辑,因为我发布以下信息的原因并不完全清楚,从评论中可以清楚地看到,让我介绍一下这个答案的其余部分:

当开始在现有代码库中使用valgrind时,几乎不可避免地会得到“假”肯定,即(尚未)真正出现问题的报告。我包含一个可能会触发此类报告的示例,以及通常修复这些报告的方式。

我只是将此包括在内,以提高对如何处理或识别(半)误报的认识。

另一种措辞方式(参考Matthieu在评论中令人信服的推理)是将“不实际杀人”的Valgrind警告视为关键:将它们固定,不要忘记

可能 valgrind在没有真正问题时会报告未初始化的访问。比如,例如

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

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

通过做更聪明的事情来解决这个问题,比如

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

确保buf中没有未初始化的“部分”(或者至少不在访问的区域内)

答案 2 :(得分:2)

使用自我初始化类来覆盖那些恼人的原语。

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; }
};

答案 3 :(得分:1)

回应评论中链接的代码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;
};

您的默认构造函数将值保持为unitialized,并以纯粹的形式反对RAII。这样做是可以的,但是当你遇到未初始化变量的问题时,我会建议删除默认的构造函数。

编辑:将未知指针存储为没有new的类成员,并且在类构造函数/析构函数中delete不是真正的RAII,但我希望你能在某处做到这一点。

答案 4 :(得分:0)

我通过使用带有模板的解决方案来解决这个问题。我使用了Property like features in C++?,但还有其他一些例子,比如传入get / setter。

本质上生成了大部分代码bc我能够并且我跟踪是否通过属性设置了变量。最后我只是检查成员并断言告诉我是否设置变量。当我得到'以防万一时,我也断言。