Pavel Pavel - 8 days ago 5
C++ Question

Accessing deleted memory

While testing my realization of stack (that is using linked list) I found one interesting thing. There is a test code to reproduce it:

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


Output:

first:0x22cfc20
p->val:0
p->prev:0x22cfc20





But if I swap the order of elements in the definition of
struct Node
like this:

struct Node {
Node *prev;
int val;
};


output will be

first:0x195dc20
p->val:40
p->prev:0





Of course it's undefined behavior in both cases but maybe it exist some rational explanation why it works this way? Or it's just random? I tried to run the code many times but it gave same output every time (except specific address value) and never crushed.

Answer

As others state, there's very little we can definitively say about this situation not only because of the undefined behavior but also because we don't know anything about the platform it was compiled on.

But there are a few things that can be said:

Changing the order of members in the struct may cause the compiler to apply different padding between the members or at the end of the struct so as to satisfy whatever alignment rules its currently compiling with.

If that did happen in this case, then it could influence the layout of memory allocated in the heap and consequently influence what data happens to get overwritten when heap space is deallocated and then reused. This could potentially explain why the results are different.