在測試我的堆棧實現(即使用鏈表)時,我發現了一件有趣的事情。有一個測試代碼重現它:訪問已刪除的內存
#include <iostream>
using namespace std;
struct Node {
int val;
Node *prev;
};
int main() {
Node *first = new Node;
first->val = 20;
first->prev = NULL;
cout << "first:" << first << endl;
Node *p = new Node;
p->val = 40;
p->prev = first;
delete p;
cout << "p->val:" << p->val << endl;
cout << "p->prev:" << p->prev << endl;
}
輸出:
first:0x22cfc20
p->val:0
p->prev:0x22cfc20
但是,如果我換元素的順序在struct Node
這樣的定義:
struct Node {
Node *prev;
int val;
};
輸出將爲
first:0x195dc20
p->val:40
p->prev:0
當然這是在兩種情況下,不確定的行爲,但也許它存在着一些合理的解釋爲什麼是這樣工作的?或者它只是隨機的?我試着多次運行代碼,但每次都輸出相同的輸出(除了特定的地址值)並且從不壓碎。
未定義的行爲並不真正_interesting_。 –
「未定義的行爲」表示「未定義的行爲」。您觀察到的實際行爲在很大程度上取決於您的實現的堆管理例程。而且由於您甚至不打算指定您的操作系統,因此無法在此處收集更多信息。 –
只要您更改編譯器選項(如優化),您的程序就可能開始有不同的表現。那麼你會看到圍繞未定義行爲的原因追逐的無用功。在某個時候,你意識到這是浪費時間,你有更好的事情要做(如開發你的應用程序)。 – PaulMcKenzie