Что делает команда delete для памяти, для указателей в C++?

Возможный дубликат:
C++ delete - удаляет мои объекты, но я все еще могу получить доступ к данным?
Можно ли получить доступ к памяти локальной переменной за пределами ее объема?

Я не понимаю, что действительно делает delete, когда я хочу освободить выделенную память new. В книге C++ Premiere написано:

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

Таким образом, я понимаю, что delete должен удалить значение в памяти, к которому относятся точки pinter. Но это не так. Здесь мой эксперимент:

int * ipt = new int;   // create new pointer-to-int

cout << ipt << endl;   // 0x200102a0, so pointer ipt points to address 0x200102a0
cout << *ipt << endl;  // 0, so the value at that address for now is 0. Ok, nothing was assigned
*ipt = 1000;     // assign a value to that memory address
cout << *pt << endl;   // read the new value, it is 1000, ok
cout << *((int *) 0x200102a0) << endl;   // read exactly from the address, 1000 too

delete ipt;   // now I do delete and then check
cout << ipt << endl;  // 0x200102a0, so still points to 0x200102a0
cout << *ipt << endl;  // 1000, the value there is the same
cout << *((int *) 0x200102a0) << endl;    // 1000, also 1000 is the value

Итак, что действительно делает delete?

Ответ 1

Подумайте о памяти как о большом складе с большим количеством ящиков, чтобы положить вещи. Когда вы называете "новым", персонал склада находит неиспользованную коробку, достаточно большую для ваших нужд, записывает эту коробку как принадлежащую вам (чтобы она не предоставлялась кому-то еще), и дает вам номер этого окна, чтобы вы могли поставить ваши вещи в него. Это число будет "указателем".

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

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

Ответ 2

Ваш эксперимент имеет undefined behavior как только вы разыщите указатель после инструкции delete. Все может случиться, что делает ваш эксперимент бесполезным.

Что делает delete (not delete[])? Он освобождает хранилище, на которое указывает его аргумент. Это вызовет запуск деструктора объекта, хранящегося в этом месте. Доступ к удаленному хранилищу вызывает неопределенное поведение (часто это segmentation fault). Нет никаких гарантий того, что память действительно будет возвращена операционной системе или что-то еще.

Ответ 3

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

То, что вы здесь испытываете, называется "неопределенным поведением" в C++. В этом случае неопределенное поведение вызвано доступом к куску памяти после его окончания жизни. Только не делай этого.

Ответ 4

Выделение указателя после delete -ing - это неопределенное поведение, поэтому все может случиться.

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

Правило большого пальца: никогда, никогда не используйте new и delete напрямую (за исключением реализации make_unique, которого по какой-то причине не хватает стандарту); используйте RAII.

Ответ 5

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

Рекомендуется delete указатель на NULL (или nullptr в С++ 11) после delete его. Любое последующее delete будет безобидным.

Ответ 6

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