Динамическое выделение памяти «удалить» - PullRequest
1 голос
/ 29 января 2011

Если я выделил ячейку памяти для объекта int динамически следующим образом:

int *x = new int;

После того, как покончено с этим и захочу освободить память в куче, я сделаю следующее:

delete x;

Теперь, если я не , сделайте следующее:

x = NULL;

Будет ли x указывать на другой адрес? ОБНОВЛЕНИЕ: another вместо many

Скажи, что я не сделал x = NULL и сделал еще delete x;, что будет?

Ответы [ 6 ]

6 голосов
/ 29 января 2011
  1. Все, что вы делаете с x (кроме = NULL - что, как мне кажется, плохая практика) после удаления, не определено.
  2. double-delete = катастрофа.

Примечание: некоторые системы времени выполнения защитят вас от некоторых очень простых случаев двойного удаления.В зависимости от деталей, вы можете быть в порядке, если вы работаете в одной из этих систем, и если никто не развертывает ваш код в другой системе, которая обрабатывает вещи по-другому, и если вы удаляете что-то, у кого нет деструктора, и есливы не делаете ничего существенного между двумя удалениями, и если никто никогда не изменяет ваш код, чтобы сделать что-то значимое между этими двумя удалениями, и если ваш планировщик потоков (над которым вы, вероятно, не имеете никакого контроля!) не переставляет потоки междудва удаляет и если, и если, и если.Итак, вернемся к Мерфи: так как он может пойти не так, он пойдет и будет работать в самый неподходящий момент.

https://isocpp.org/wiki/faq/freestore-mgmt

5 голосов
/ 29 января 2011

После delete указатель обычно будет по-прежнему содержать адрес (теперь свободной) памяти.Второй delete дает неопределенное поведение, поэтому не делайте этого.

2 голосов
/ 29 января 2011

тип:

int main(){
  int* i = new int;
  std::cout << i << std::endl;
  delete i;
  std::cout << i << std::endl;
  delete i;
}

результат:

0x8e19008

0x8e19008

** обнаружен glibc ** ./a.out: double freeили повреждение (fasttop): 0x08e19008 *

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

2 голосов
/ 29 января 2011

Это вызовет неопределенное поведение.Если вы не сделаете x=NULL, то x будет указывать на недопустимую область памяти, которая при попытке использования приведет к неопределенному поведению.

1 голос
/ 29 января 2011

Второе удаление не определено.

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

1 голос
/ 29 января 2011

вызов delete на уже удаленной памяти вызовет неопределенное поведение. Обычно ваша программа аварийно завершает работу.

После удаления x, куда он будет указывать, «зависит от компилятора». Большинство компиляторов будут просто указывать, где оно было, до вызова delete. Но этот адрес памяти больше не действителен и, следовательно, не должен вызываться.

По этой же причине «удалить это» следует использовать очень разумно и осторожно, если это вообще необходимо. : -)

...