C `gdb'对'ret'和自然回报给出了不同的结果

C `gdb'对'ret'和自然回报给出了不同的结果,c,arrays,memory,gdb,segmentation-fault,C,Arrays,Memory,Gdb,Segmentation Fault,我有以下功能: 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) {

我有以下功能:

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


关于手动通过函数“
n
exeig”和强制返回时返回值之间存在这种差异的原因,有什么建议吗?

在函数中,如果您保证es的值是正确的,那么在调用之后,new的值应该是正确的

也许,我想

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

在malloc之后不检查
es
的值。确保malloc不返回NULL。。此外,如果所有传入边都匹配,循环将以
num_edges==g->num_edges
结束,并且
NULL
的最后一次哨兵写入将溢出缓冲区。危险!这突出了我的一个错误假设,即
gdb
中的
ret
执行函数直到自然返回,但事实上它丢弃了堆栈帧,因此我要将其标记为正确。另外注意,
gdb
中的
finish
是我应该使用的命令,继续执行直到自然恢复。
First, check the es;
Then, compare the return value of new with es.