我正在做一个游戏。在某些地方,有时我会收到分段错误,而在所有其他时候代码都能正常工作。如果我再次运行游戏(在收到分段错误后),它会恢复回来(没有任何代码更改)并运行良好。但过了一段时间,这种情况又发生了。
我尝试使用 GDB 调试它。我得到了以下信息:
- 有一个函数调用:func(&s.x),其中 s 是一个结构体,x 是它的 int 类型成员。地址 (&s.x) 为0xb3456721
- 在函数函数中,参数中收到的值0xb。
- 程序崩溃,指出无法访问0xb的内存。当我使用 GDB 打印变量时,我再次收到无法访问内存。
任何想法为什么会发生这种情况?
在给定相同输入时有时会崩溃但有时不会崩溃的程序具有非确定性数据源。 通常,源是未初始化的变量或内存块,但它可能依赖于时间戳、进程 ID 或来自系统的其他输入源,这些输入源会有所不同。
我之前在 Linux 上成功地使用 valgrind 来调试由未初始化变量引起的非确定性行为。
这是我使用valgrind
命令,您的程序和选项应遵循
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes -v
如果您在Windows上运行,请查看此答案以获取valgrind
替代品
有没有一个好的Valgrind替代品来代替Windows?
您的程序是多线程的吗? 非确定性的一个来源是竞争条件。
由于 C++ 标签存在,但您说您正在调用 then 函数: func(&s.x)
,然后鉴于func
说它在其参数参数中收到了0xb
,这让我相信s
实际上是一个不正确初始化的引用。例如,考虑:
struct foo {
char a[12];
int x;
};
void func (int *x) {
*x = 0;
}
int main () {
foo *sp = (foo *)-1;
foo &s = *sp;
func(&s.x);
}
由于您没有提供足够的信息,因此无法诊断问题的确切性质。