今日免费次数已满, 请开通会员/明日再来

4
我在类的私有部分定义了一个枚举类型。我也定义了一个此类型的成员。当我试图在构造函数中初始化这个成员时,运行时会出现内存损坏问题。但是,如果我在同一个构造函数中使用初始化列表来初始化它,就不会出现内存损坏问题。我做错了什么吗?
我将代码简化了一下,如果这是GCC的bug,我确信它是我组合/继承/等所特定的类的组合,但我保证这捕捉了问题的本质。在初始化这个成员之前没有任何东西使用它,并且在完全构建之前没有任何东西使用新创建的对象。这个成员的初始化确实是我在构造函数体中做的第一件事情,当发生内存损坏时,valgrind说它在初始化变量的那一行上。Valgrind说这是4字节大小的无效写入。
相关头文件代码: private: enum StateOption{original = 0, blindside}; StateOption currentState;
相关.cpp代码(导致内存损坏和崩溃):
MyClass::MyClass(AClass* classPtr) : BaseClass(std::string("some_setting"),classPtr) { currentState = original; ... }
相关.cpp代码(不会导致内存损坏和崩溃):
MyClass::MyClass(AClass* classPtr) : BaseClass(std::string("some_setting"),classPtr), currentState(original) { ... }
编辑:看到我的“答案”后,有人能解释一下为什么会有区别吗?我没有在头文件中更改任何内容,显然由于我的打印语句出现在我放置它们的位置并且在一个构建中没有看到错误而在另一个构建中看到了错误,因此对象文件正在重新构建。

如果删除 private:,它还能正常工作吗? - Marcelo Cantos
@Bart 我也没有遇到硬性停止的情况。当我不使用valgrind时,我会收到“glibc detected”提示,然后程序会卡住。而当我使用valgrind时,就像之前说的那样。 - San Jacinto
你尝试过添加另一个成员,比如int类型,或者用int替换枚举吗?也许是你的基础构造函数越界了,在第二种情况下valgrind才能捕捉到。 - jv42
@Marcelo 它表现出相同的行为。 - San Jacinto
提供一个真实的测试案例。以上代码没有提供足够的上下文来诊断此问题。 - wilx
显示剩余13条评论
1个回答

1

为了后人纪念:

看起来制作脚本由于某些原因没有捕捉到这些文件的更改。手动删除对象而不是让我们在 makefile 中的“clean”目标导致了完全重建(需要一些时间),问题就消失了。


可能的原因是您修改了 Makefile 文件。 - mip
添加ccache(http://ccache.samba.org/)将大大缩短重新编译时间。 - Mr.Ree
最常见的原因是Makefile没有表达目标文件和头文件之间的依赖关系,因此更改头文件会导致无法重新编译所有依赖于它的代码。 - Marcelo Cantos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接