Доступ к удаленной памяти

При тестировании моей реализации стека (то есть с использованием связанного списка) я обнаружил одну интересную вещь. Существует тестовый код для его воспроизведения:

#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

Конечно, это неопределенное поведение в обоих случаях, но, может быть, существует какое-то рациональное объяснение, почему это работает таким образом? Или это просто случайно? Я пытался запустить код много раз, но он каждый раз давал один и тот же вывод (кроме определенного значения адреса) и никогда не давал результатов.

-1

Решение

Как утверждают другие, мы очень мало можем определенно сказать об этой ситуации не только из-за неопределенного поведения, но и потому, что мы ничего не знаем о платформе, на которой она была скомпилирована.

Но есть несколько вещей, которые можно сказать:

Изменение порядка элементов в структуре может привести к тому, что компилятор применяет различные отступы между элементами или в конце структуры, чтобы удовлетворить любые правила выравнивания, с которыми он в данный момент компилируется.

Если это произошло в этом случае, то это может повлиять на расположение памяти, выделенной в куче, и, следовательно, повлиять на то, какие данные перезаписываются, когда пространство кучи освобождается и затем используется повторно. Это может потенциально объяснить, почему результаты отличаются.

2

Другие решения

Неопределенное поведение просто не определяет никакого конкретного поведения совсем. Реализация может быть разрешена для того, чтобы заставить вашу программу работать или выключить компьютер, отформатировать жесткий диск, открыть черную дыру внутри вашей кошки и даже открыть кошку внутри вашей черной дыры.

Большая часть реализации остановит выполнение, если программа попытается выполнить недопустимую операцию с памятью. Когда-нибудь, если вам не повезет, ваша программа будет работать нормально, как и ваш пример.

С учетом вышесказанного: Есть сотни причин, по которым вы могли бы получить доступ к удаленной памяти, но любые предположения относительно такого поведения являются недопустимыми и могут привести к разным результатам по любой причине.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector