【问题标题】:set a breakpoint in malloc_error_break to debug in C++在 malloc_error_break 中设置断点以在 C++ 中进行调试
【发布时间】:2012-11-06 10:15:23
【问题描述】:

我正在编写一个带有 2 个命令行参数的程序:分别为 ab

只要a <= 17.5一切都好

一旦a > 17.5 程序抛出以下错误:

已释放对象的校验和不正确 - 对象可能在被释放后被修改

我已将问题缩小到以下代码段:

for(int a=0; a < viBrickWall.size(); a++) {
    vector<int64_t> viTmp(iK-i);
    fill(viTmp.begin(),viTmp.end(),2);

    for(int b = 0; b < viBrickWall[a].size(); b++) {
         viTmp[viBrickWall[a][b]] = 3;
    }

    viResult.push_back(viTmp);
    viTmp.clear();
}

删除后一段代码,消除了错误。

我也在用valgrind调试内存,但是一直没找到解决办法。

这是 valgrind 报告的副本:

Report hosted in pastebin

编辑

我用调试标志编译了程序:

g++ -g -O0 -fno-inline program.cpp

并使用 valgrind 运行它,如下所示:

` valgrind --leak-check=full --show-reachable=yes --dsymutil=yes ./a.out 48 10 ``

我注意到下面一行:

 ==15318== Invalid write of size 8
 ==15318==    at 0x100001719: iTileBricks(int) (test.cpp:74)
 ==15318==    by 0x100001D7D: main (test.cpp:40)

第 74 行是:

viTmp[viBrickWall[a][b]] = 3;

第 40 行是:

viBrickWall = iTileBricks(iPanelWidth);

【问题讨论】:

  • 您需要使用调试信息进行编译才能获得有用的valgrind 输出。
  • 嗨大卫,谢谢你的提示。我更新了帖子,进一步缩小了问题的范围。你介意看看吗?
  • valgrind 输出的第 13-19 行显示了问题。在这些代码行中添加assert(或打印)语句可能有助于发现问题。
  • @DavidSchwartz 感谢您指出这一点!太棒了:)我会看看。
  • viTmp[viBrickWall[a][b]] = 3; 在行前添加大量asserts。确保a 在范围内并且b 在范围内。然后确保viBrickWall[a][b] 在范围内。

标签: c++ memory-leaks gdb valgrind


【解决方案1】:

您正在使用此行导致对堆内存的无效写入:

viTmp[viBrickWall[a][b]] = 3;

这意味着当时viBrickWall[a][b]viTmp 之外建立索引。添加

int i = viBrickWall[a][b];
assert(0 <= i && i < viTmp.size());

店前到viTmp[i] = 3.

提示:也许将 viTmp 的大小增加一可以解决它:

-vector<int64_t> viTmp(iK-i);
+vector<int64_t> viTmp(iK - i + 1);

我不知道 viBrickWall 的内容,所以这只是 Valgrind 输出的有根据的猜测。

我不确定您是在 Mac OSX 上使用 GNU libstdc++ 还是 libc++。如果您使用libstdc++ 或手边有Linux 机器,请将viTmp 声明为std::__debug::vector 会很快发现此问题。

【讨论】:

  • 斯科特非常感谢您的洞察力。我在查看您的答案之前解决了问题,但您是对的 :) 非常感谢。
猜你喜欢
  • 2012-12-12
  • 2012-05-22
  • 2018-07-29
  • 2023-03-29
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 2021-05-27
  • 2017-04-17
相关资源
最近更新 更多