Segfault问题与结构内部的结构数组

时间:2011-03-15 14:44:18

标签: c++ c nested segmentation-fault structure

编辑:第一位评论者报告代码没有明显错误,因此我修改了帖子中包含更多代码。道歉的长度。当我在子结构中引用字符串变量时,错误似乎再次出现...请注意,如果由于写入另一个字符串var而删除了稍后在segfaults中导致segfault的第一次写入。请注意,在这种情况下,子结构的其他元素(例如double Volume)被正确写入而没有运行时错误。

编辑2: 根据Dave的建议,我在调试启用的可执行文件上运行了Valgrind。吐出来的是:

编辑3: 显然我在初始化程序中有一个malloc而不是直接数组的版本。删除此修复了问题。我会给Dave充分的信任,因为valgrind正在帮我修复各种其他的memleaks /问题!谢谢你的帮助,不过......

第36行是失败的(下面评论)

- 删除代码以防止传播

我在main中声明了我的顶级结构(sim_t)的实例。一旦我尝试写入子结构内的字符串,程序就会出现段错误。写入子结构的其他变量,例如当我在GDB中运行程序时,双打,整数等似乎正确执行。

似乎有一些明显我在这里缺失的东西。有没有人看到这段代码的问题?

(并且为了记录,请不要对大小写做出评论,我遵循MSDN的命名约定标准。)

3 个答案:

答案 0 :(得分:2)

我猜你正在堆满了。如果NUMBEROFBOXESsizeof(box_t)都有点大,那么sizeof(sim_t)会非常大,然后即使sim_t的单个实例也会溢出您的堆栈。

如果无法以任何方式减少sizeof(sim_t),那么您需要在堆上(例如使用new)或静态存储(例如作为全局变量)分配对象)。


修改

我仍然怀疑堆栈溢出,但此时仍然很难说。在GDB下运行您的程序并运行这些命令并告诉我们结果如何:

$ gdb myprogram
(gdb) run
...
Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
...
(gdb) list
...
(gdb) disas
...
(gdb) info reg
...
(gdb) info inferior
...

最后一个命令为您提供程序的PID。然后,从另一个终端运行以下命令:

# Replace PID here with the PID of the program being debugged above
$ cat /proc/PID/maps

来自这些命令的信息应该有助于确定问题是否是由堆栈溢出引起的。

答案 1 :(得分:2)

您在每次迭代时都将“boxX_start.pdb”添加到stringstream而不清除流。使用较大的NUMBEROFBOXES值,内存使用量可能会非常快速地增加。试试这个

void InitSimpleVars(sim_t & MySim)
{
  std::stringstream in;

  MySim.StartTime = clock();

  //INITIALIZE Box Sim Vars...                                                                                
  for (unsigned int BoxNumber = 0; BoxNumber < NUMBEROFBOXES; BoxNumber++)
    {
      in.str("");                                                                                           
      in << "box" << BoxNumber << "_start.pdb";
      MySim.Box[BoxNumber].InitialConfigPDB = in.str(); //SEGFAULT HERE, according to GDB                     
    }
}

添加in.str(“”);清除流。可能有更好的方法来清除它,但如果有的话我就不知道了。

答案 2 :(得分:2)

如果使用-Wall编译它,您是否可能收到有关打包更改的警告?在标准库标题之前,由于#pragma pack,我遇到了类似的崩溃。

或者,在更多地查看您的代码之后,可能会将您的BOX1BOX2定义更改为0和1,而不是1和2 - 假设您的数组只有2个框。