【问题标题】:`gdb` gives different results for `ret` and natural return`gdb` 给出了 `ret` 和自然返回的不同结果
【发布时间】:2013-12-13 10:11:56
【问题描述】:

我有以下功能:

edge** graph_out_edges(graph* g, int src) {
    int i;
    int num_edges = 0;
    edge** es = (edge**) malloc(sizeof(edge*) * g->num_edges);

    for (i = 0; i < g->num_edges; i++) {
        if (src == g->edges[i]->src) {
            es[num_edges++] = g->edges[i];
        }
    }

    es[num_edges] = NULL;
    return es;
}

我使用b graph_out_edges 向函数添加断点,使用r 运行程序,然后继续(c) 两次(如果我再次继续,则会出现段错误)。然后我通过函数n 直到它在调用函数之后移动到命令

edge** new = graph_out_edges(g, min->dest);

p new[0]p new[1] 提供有效边(成员已填充),p new[2] 提供0x0,正如预期的那样。然后我输入r重新启动程序,再次继续两次,但这次我输入ret(确认我想返回),输入n执行分配,但现在当我输入p new[0]我得到

Cannot access memory at address 0x2

(为了清楚起见,p new 现在说$10 = (edge**) 0x2

关于为什么手动通过函数“nexting”和强制返回时返回值之间存在这种差异的任何建议?

【问题讨论】:

  • 你没有在 malloc 之后检查es 的值。确保 malloc 不返回 NULL。
  • Please don't cast the return value of malloc() in C。此外,如果所有传入的边都匹配,则循环将以num_edges == g-&gt;num_edges 结束,NULL 的最终标记写入将溢出缓冲区。危险!

标签: c arrays memory gdb segmentation-fault


【解决方案1】:

在函数中,如果保证es的值是对的,那么调用后new的值应该是对的。

也许,我想,

First, check the es;
Then, compare the return value of new with es.

【讨论】:

  • 这突出了我的一个错误假设,即gdb 中的ret 执行该函数直到自然返回,但实际上它丢弃了堆栈帧,因此我将其标记为正确.
  • 补充说明,gdb 中的finish 是我应该使用的命令,它会继续执行直到自然返回。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2014-01-24
相关资源
最近更新 更多