Я заметил кое-что очень странное в моем коде 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()
потерпит неудачу Но во время выполнения этого кода он работает и даже печатает «привет».
Зачем?
Я думал что delete сотрет память из кучи
Единственный способ «стереть» память — молотком.
Память помечена как «неиспользованная», а объект семантически уничтожен.
а также
b->doIt()
потерпит неудачу
Почему это?
Там нет никакого механизма, чтобы сделать это для вас, ни можно там быть один в общем случае.
Это ваш ответственность не вызывать функции на объектах, которые не существуют.
Говоря практически, он не падает здесь, потому что ничего в doIt
на самом деле пытается получить доступ к памяти объекта. Помните, что функция не хранится «в» объекте — она является частью вашей программы, и ваша программа все еще существует.
Даже если doIt
доступ и / или видоизменение состояния объекта, пока эта память все еще находилась на активной странице, вы, вероятно, еще не получить крах. Именно поэтому неопределенное поведение определяется как непредсказуемый.
Избегайте.
Скорее всего, потому что doIt
Метод не использует внутреннее состояние класса А. Поэтому компилятор, вероятно, оптимизировал его для статического метода, и вызов вызывается в контексте статического класса. Тот факт, что указатель свисает, не мешает запуску метода.
Тем не менее, это неопределенное поведение, и более строгие компиляторы могут на самом деле создавать код, который действительно дает сбой.