一台 Linux 机器上的分段错误,但另一台机器上没有 C++ 代码

Segmentation fault on one Linux machine but not another with C++ code

我遇到了一个奇怪的问题。我在工作中的 Linux 集群上开发了一个 C++ 程序。我曾尝试在 Ubuntu 14.04 机器上使用它,但该程序由 6 个文件组成:main.hpp、main.cpp(取决于)sarsa.hpp、sarsa.cpp (class Sarsa) (依赖于) wec.hpp,wec.cpp, 编译, 但是当我 运行 它要么 returns segmenation fault或不输入classSarsa.

的一个基本函数

主代码调用构造函数和setter函数没有问题:

  Sarsa run;
  run.setVectorSize(memory,3,tilings,1000);

等等

但是,它不能 运行 public 函数 episode ,因为 learningRate 应该包含一个大整数,returns 0 对于所有剧集(迭代)。

learningRate[episode]=run.episode(numSteps,graph);}

我尝试用 gdb 调试代码,结果返回:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000408f4a in main () at main.cpp:152
152     learningRate[episode]=run.episode(numSteps,graph);}

我也试过valgrind,结果返回:

==10321==  Uninitialised value was created by a stack allocation
==10321==    at 0x408CAD: main (main.cpp:112)

但没有内存泄漏问题。

我想知道是否有尝试调试外部文件 sarsa.cpp 的设置,因为我认为 class 可能是罪魁祸首

在文件中,我使用了 C++v11 语言(虽然我预计会在编译时出错),所以我什至用 g++ -std=c++0x 编译,但没有任何改进。

不幸的是,由于代码的大小,我无法在此处post。我真的很感激任何帮助解决这个问题。我错过了什么明显的东西吗?你能帮我至少调试一下吗?

提前感谢您的帮助。

更正: main.cpp:

全局数组的定义: `#define numEpisodes 10

int learningRate[numEpisodes];`

main 函数即将结束:

for (int episode; episode<numEpisodes; episode++) { if (episode==(numEpisodes-1)) { // Save the simulation data only at the graph=true;} // last episode learningRate[episode]=run.episode(numSteps,graph);}

分段错误表示无效的内存访问。通常这意味着在某处,您正在读取或写入超出数组末尾的位置,或者通过无效指针,或者通过已释放的对象。您不一定会在错误发生的地方遇到分段错误;例如,您可以将数组末尾写入堆元数据,这会在稍后尝试分配或释放不相关对象时导致崩溃。因此,一个程序在一个系统上运行正常但在另一个系统上崩溃是完全合理的。

在这种情况下,我会先查看 learningRate[episode]episode 的值是多少?是否在 learningRate 范围内?

I was wondering if there was a setting to try to debug the external file sarsa.cpp, since I think that class is likely to be the culpript

It's possible to set breakpoints in functions other than main.cpp.

break location

Set a breakpoint at the given location, which can specify a function name, a line number, or an address of an instruction.

至少,我认为这是你的问题。 You'll also need to know how to step into functions.

更重要的是,您需要了解您的工具试图告诉您什么。段错误是操作系统对试图取消引用不属于您的内存的反应。一个常见的原因是试图取消引用 NULL。另一个将尝试取消引用从未初始化的指针。 Valgrind 错误消息表明您可能有一个未初始化的指针。

如果没有代码,我无法告诉您为什么当您 运行 您的家庭系统上的程序时指针没有被初始化,但是当您 运行 它时(显然)被初始化在上班。我怀疑您的家庭系统上没有必要的数据,但您需要调查并弄清楚这一点。不断问自己的基本问题是“我的家用电脑和我的工作电脑有什么不同?”

正如您刚刚添加到问题中的代码所揭示的那样,出现问题是因为您没有初始化 episode 变量。在您分配一个值之前使用其值的任何代码的行为是未定义的,因此程序在一个环境中的行为与在另一个环境中的行为不同是完全合理的。