Оборванные указатели и команда удаления в переполнении стека

Я заметил кое-что очень странное в моем коде C ++.

class A
{
public:
void doIt(){cout<<"hello"<<endl;}
};
int main() {
A* a=new A();
A* b=a;
delete a;
b->doIt();
return 0;
}

я думал так delete сотрет память из кучи и b->doIt() потерпит неудачу Но во время выполнения этого кода он работает и даже печатает «привет».

Зачем?

0

Решение

Я думал что delete сотрет память из кучи

Единственный способ «стереть» память — молотком.

Память помечена как «неиспользованная», а объект семантически уничтожен.

а также b->doIt() потерпит неудачу

Почему это?

Там нет никакого механизма, чтобы сделать это для вас, ни можно там быть один в общем случае.

Это ваш ответственность не вызывать функции на объектах, которые не существуют.

Говоря практически, он не падает здесь, потому что ничего в doIt на самом деле пытается получить доступ к памяти объекта. Помните, что функция не хранится «в» объекте — она ​​является частью вашей программы, и ваша программа все еще существует.

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

Избегайте.


4

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

Скорее всего, потому что doIt Метод не использует внутреннее состояние класса А. Поэтому компилятор, вероятно, оптимизировал его для статического метода, и вызов вызывается в контексте статического класса. Тот факт, что указатель свисает, не мешает запуску метода.

Тем не менее, это неопределенное поведение, и более строгие компиляторы могут на самом деле создавать код, который действительно дает сбой.

1

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