我遇到了一种奇怪的malloc行为,并且正在跳跃,有人可以对它进行一些说明。
这是一个功能:
struct flowNetwork * createGraph(){
struct flowNetwork * fN = initFlowNetwork();
insertAdjMatrix(fN->adjMatrix, 0, 3, 0, 10);
insertAdjMatrix(fN->adjMatrix, 0, 2, 0, 12);
insertAdjMatrix(fN->adjMatrix, 0, 1, 0, 5);
insertAdjMatrix(fN->adjMatrix, 1, 4, 0, 6);
insertAdjMatrix(fN->adjMatrix, 2, 5, 0, 11);
insertAdjMatrix(fN->adjMatrix, 4, 5, 0, 5);
insertAdjMatrix(fN->adjMatrix, 3, 5, 0, 5);
insertAdjMatrix(fN->adjMatrix, 3, 7, 0, 5);
insertAdjMatrix(fN->adjMatrix, 4, 5, 0, 5);
insertAdjMatrix(fN->adjMatrix, 5, 7, 0, 10);
insertAdjMatrix(fN->adjMatrix, 5, 6, 0, 8);
insertAdjMatrix(fN->adjMatrix, 7, 8, 0, 16);
insertAdjMatrix(fN->adjMatrix, 6, 8, 0, 9);
return fN;
}
注意第二行调用一个函数,它将返回一个指向flowNetwork结构的指针。这是功能的代码:
struct flowNetwork * initFlowNetwork(){
struct flowNetwork * N = (struct flowNetwork *)malloc(sizeof(struct flowNetwork));
N->adjMatrix = initAdjMatrix();
int i;
for (i = 0; i < NODES; i++)
{
N->visitedNodes[i] = 0;
N->parent[i] = -1;
}
}
请注意,我从未返回指针(我原本忘记添加它并稍后注意到)。尽管没有返回代码,但代码完全正常,就像我确实有一个返回指针语句一样 有谁知道为什么这有效?
答案 0 :(得分:4)
纯粹的运气。事实上,C表示&#34;忘记&#34;具有非void返回类型的函数中的return语句会导致未定义的行为,即可能发生任何事情,您的程序可能崩溃,您的房子可能会烧毁,您的编译器可能会启动它自己的SkyNet实例...有谁知道为什么会这样?
这里的要点是你的编译器可能只是将它作为一种好的方式。我认为不应该这样。尝试使用-Wall
进行编译,您会看到更多警告。
在x86上,这不会发生意外。返回值通常存储在CPU寄存器%eax
中,如果您没有明确地返回指针,那么它就没有理由存在于该寄存器中。但是,在函数中写入%eax
的最后一个是malloc
,并且由于malloc
的返回值(新分配的空间的地址)与返回值相同你想要制作,即新flowNetwork
的地址,这恰好起作用。颤动!
编辑更清楚:我的意思是&#34;编译器很好&#34;就是它不会尖叫到你的脸上,告诉你你犯了一个可怕的错误,而不是它神奇地回归正确的价值。
答案 1 :(得分:0)
你正在返回堆栈中的任何内容,这些内容可能是指向某些可用内存的指针,而这些内存会因不可预测的副作用而消失。
解决方案:不要这样做。
答案 2 :(得分:0)
每当有一个函数应该返回一些东西而且它包含一个局部变量。本地变量占据函数调用堆栈的顶部位置。当这样的函数返回时,堆栈顶部没有返回语句值是poped。在你的情况下它是N. 请参阅此link