结构内部结构数组的段错误问题

发布于 2024-10-21 19:17:44 字数 668 浏览 4 评论 0原文

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

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

编辑3: 显然我有一个版本,它使用 malloc 而不是初始化程序内的直接数组。删除这个问题就解决了。我将给予 Dave 充分的信任,因为 valgrind 正在帮助我修复各种其他 memleaks/问题!不过,谢谢您的帮助...

第 36 行是它失败的地方(下面有评论)

--代码被删除以防止传播

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

看来我在这里遗漏了一些明显的东西。有人看到这段代码有问题吗?

(郑重声明,请不要对大小写发表评论,我遵循 MSDN 的命名约定标准。)

Edit: The first commenter reports that the code has no apparent errors, so I've revised the post with more code. Apologies for the length. Again the error appears to be when I reference the string vars in the substructure... note that if I remove the first write that causes the segfault in segfaults later on due to a write to the other string var. Note that in this scenario other elements of the substructure (e.g. the double Volume) are correctly written without runtime error.

Edit 2:
As per Dave's suggestion, I ran Valgrind on the debugging enabled executable. What it spit out was :

Edit 3:
Apparently I had a version that malloc instead of a direct array inside the initializer. Removing this fixed the problem. I'll give Dave full credit for this one as valgrind is helping me fix all sorts of other memleaks/issues! Thank you for your help, though....

Line 36 is the one it fails on (commented below)

--code removed to prevent dissemination

I declare an instance of my top level struct (sim_t) in main. The program segfaults as soon as I try to write to the strings inside the substructure. Writes to other vars of the substructure e.g. doubles, ints, etc. appeared to correctly execute when I ran the program in GDB.

It seems like there's something obvious I'm missing here. Does anyone see the problem with this code?

(And for the record, please don't make comments about the capitalization, I'm following MSDN's naming convention standard.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不醒的梦 2024-10-28 19:17:44

您在每次迭代时将“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("");清除流。可能有更好的方法来清除它,但我不知道是否有。

You are adding "boxX_start.pdb" to stringstream on every iteration without clearing the stream. Memory usage could add up very quickly with a large NUMBEROFBOXES value. Try this

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

adding in the in.str(""); to clear the stream. There may be a better way to clear it, but I'm not aware of it if there is.

晌融 2024-10-28 19:17:44

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

或者,在进一步查看代码后,也许将您的 BOX1BOX2 定义更改为 0 和 1,而不是 1 和 2 - 考虑到您的数组只有 2 个框。

If you compile this with -Wall do you perhaps get warnings about packing changes? I've had similar crashes due to #pragma pack before standard library headers.

Or, after some more looking at your code, perhaps change your BOX1 and BOX2 defines to 0 and 1, not 1 and 2 - given that your array has only 2 boxes.

好多鱼好多余 2024-10-28 19:17:44

我猜你的堆栈溢出了。如果 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

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

I'm guessing you're overflowing the stack. If both NUMBEROFBOXES and sizeof(box_t) are somewhat large, then sizeof(sim_t) is going to be very large, and then even a single instance of sim_t will overflow your stack.

If you can't reduce sizeof(sim_t) in any way, then you'll need to allocate your object on either the heap (e.g. with new) or in static storage (e.g. as a global variable).


EDIT

I still suspect a stack overflow, but it's still hard to say at this point. Run your program under GDB and run these commands and tell us what the results are:

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

The last command gives you the PID of the program. Then, from another terminal, run this command:

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

The information from these commands should help determine whether or not the problem is being caused by a stack overflow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文