![](/img/trans.png)
[英]Weird behaviour of function with malloc() and realloc() resulting in Segmentation Fault
[英]Weird malloc behaviour
我遇到了一個奇怪的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;
}
}
請注意,我從未返回過指針(我最初忘記添加它,並在以后注意到了)。 盡管沒有返回代碼,但代碼的工作就像我確實有一個返回指針語句一樣。
誰知道為什么這樣嗎?
誰知道為什么這樣嗎?
真幸運。 實際上,C表示“忘記”具有非空返回類型的函數中的return語句會導致未定義的行為 ,即,任何事情都可能發生,程序可能崩潰,房屋可能燒毀,編譯器可能會啟動自己的實例天網的...
這里的要點是,您的編譯器可能只是將此作為一種很好的手段。 我認為不應該。 嘗試使用-Wall
編譯,您將看到更多警告。
在x86上,這不會偶然發生。 返回值通常存儲在CPU寄存器%eax
,如果沒有顯式返回指針,則沒有理由將指針放在該寄存器中。 不過,最后一個寫%eax
在功能malloc
,由於返回值malloc
,新分配空間的地址是一樣的,你要生產的返回值,新的即地址flowNetwork
這恰好起作用。 不寒而栗!
編輯得更清楚:“編譯器很好”的意思是它不會尖叫到您的臉上,告訴您您犯了一個可怕的錯誤,而不是神奇地返回了正確的值。
您將返回堆棧中的任何內容,這可能是指向某些可用內存的指針,這些內存浪費了不可預測的副作用。
解決方案:不要那樣做。
每當有一個應該返回某些東西的函數並且它包含一個局部變量時,局部變量在函數調用棧中占據頂部位置。當這樣的函數返回而沒有返回聲明值在棧頂時被彈出。您的情況是N。請參閱此鏈接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.