Подтвердить что ты не робот

Что происходит, когда вы удаляете указатель дважды или больше на С++?

int main(){
Employee *e = new Employee();

delete e;
delete e;
...
delete e;
return 0;

}
4b9b3361

Ответ 1

e не ссылка, это указатель. Вы получаете поведение undefined, если вы пытаетесь delete объект через указатель больше, чем один раз.

Это означает, что почти все может произойти от "появления работы" до "сбоев" или чего-то совершенно случайного.

Ответ 2

Это поведение undefined, поэтому все может случиться.

Скорее всего, это плохо. Как правило, бесплатный магазин представляет собой тщательно управляемую систему свободных и выделенных блоков, а new и delete выполняет бухгалтерию, чтобы сохранить все в согласованном состоянии. Если вы снова delete, система, скорее всего, сделает ту же самую учетную запись на недопустимых данных, и внезапно свободное хранилище находится в несогласованном состоянии. Это известно как "кучное повреждение".

Как только это произойдет, все, что вы делаете с new или delete, может иметь непредсказуемые результаты, которые могут включать в себя попытку писать за пределами области памяти приложения, бесшумно искажая данные, ошибочно полагая, что больше нет памяти или двойное или перекрывающееся распределение. Если вам повезет, программа скоро выйдет из строя, хотя у вас все еще будут проблемы с выяснением причин. Если вам не повезло, он будет продолжать работать с плохими результатами.

Ответ 3

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

Ответ 4

Вероятно, вы впадаете в область поведения undefined.

Во многих системах это приведет к сбою; например, на моей машине Linux:

*** glibc detected *** ./cctest: double free or corruption (fasttop): 0x0000000000d59900 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f399f4cbdd6]
/lib/libc.so.6(cfree+0x6c)[0x7f399f4d074c]
./cctest[0x400a7a]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f399f474abd]
./cctest[0x400959]

Ответ 5

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

В проверенных или отладочных сборках часто такие вещи пойманы, но они могут полностью исчезнуть и вызвать хаос позже. Это особенно важно, когда задействованы несколько потоков.

Ответ 7

Если вы опасаетесь, что это может случиться в ваших приложениях, либо полностью прекратите использование исходных указателей, чтобы вам не нужно было удалять (например, переключиться на shared_ptr), либо всегда устанавливать указатели на NULL (или 0, или еще лучше nullptr) после их удаления. Вызов удаления по нулевому указателю гарантированно ничего не делает.