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

int main(){ Employee *e = new Employee(); delete e; delete e; ... delete e; return 0; } 

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

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

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

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

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

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

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

Во многих системах это приведет к сбою; например, на моей машине 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] 

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

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

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

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

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

  • Что такое тип данных uintptr_t
  • Причина, почему бы не иметь макрос DELETE для C ++
  • Как выровнять указатель в C
  • Почему некоторые люди предпочитают «T const &» над «const T &»?
  • Могу ли я взять адрес элемента «один конец прошлого» массива?
  • Неинициализированные указатели в коде
  • Использование стрелки (->) в C
  • Адрес массива
  • Почему бы не использовать указатели для всего на C ++?
  • Создать новый объект C ++ по определенному адресу памяти?
  • Преобразование указателя в указатель между производными и базовыми classами?
  • Давайте будем гением компьютера.