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

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

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

}
23
задан Michael Mrozek 30 April 2010 в 18:26
поделиться

7 ответов

e не ссылка, это указатель. Вы получите неопределенное поведение , если попытаетесь удалить объект с помощью указателя более одного раза.

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

38
ответ дан 29 November 2019 в 00:47
поделиться

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

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

3
ответ дан 29 November 2019 в 00:47
поделиться

Это неопределенное поведение, так что все может случиться.

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

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

18
ответ дан 29 November 2019 в 00:47
поделиться

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

11
ответ дан 29 November 2019 в 00:47
поделиться

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

3
ответ дан 29 November 2019 в 00:47
поделиться

Вы, вероятно, рискуете выйти на территорию «неопределенного поведения».

На многих системах это вызовет сбой; например, на моем компьютере с 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]
4
ответ дан 29 November 2019 в 00:47
поделиться

Это небезопасно, и неизвестно, что может произойти на самом деле:

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.2

2
ответ дан 29 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: