2015-02-23 2 views
4

Почему в стеке вызовов после delete this; вызывается следующая функция?Удалить вызовы memset?

msvcr110d.dll!_VEC_memset(void * dst, int val, int len) 

Пожалуйста, обратите внимание, что operator delete не перегружена.

+3

вы в режиме отладки или режиме выпуска? – Brandon

+5

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

+0

Просмотр некоторых [обсуждений в MSDN] (https://social.msdn.microsoft.com/Forums/en-US/a51fe950-cd74-4133-8d84-1bc07b353bc2/msvc-2005-automatically-calling-memset?forum=Vsexpressvc) похоже, что это может быть частью оптимизации компилятора MSVC. Если вы установите «Оптимизация» на «Оптимизировать скорость» в параметрах проекта, она должна исчезнуть. – AndyG

ответ

7

В отладочной версии библиотеки времени выполнения Microsoft C/C++ delete устанавливает освобожденную память в 0xDD с использованием memset. Вот почему вы видите memset в callstack. Вы не увидите его в версии выпуска.
Аналогично, когда память распределяется через new, вновь выделенная память установлена ​​в 0xCD.

Вы можете увидеть некоторые детали здесь - https://msdn.microsoft.com/en-us/library/974tc9t1.aspx

+0

Является ли также нормальным для доступа к этой памяти после удаления и не имеет аварийного отключения приложения в режиме отладки? –

+0

@TM_ это возможно и в выпуске. Доступ к памяти после удаления - неопределенное поведение. Все может случиться, включая великие вещи или плохие вещи. – user93353

+0

Я проверил значение destructed 'bool' is' true (254) ', а значение destructed' int' - '-17891602' –

3

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

Также при повторном использовании блока можно определить, кто-то написал в область после ее удаления.

+0

Итак, удалив его, я все еще могу использовать этот объект, если помню адрес? –

+1

@TM_: NO. Не используйте объект после его удаления. Это неопределенное поведение. – NathanOliver

+0

@TM_: Нет. Вы не можете, но это обычная ошибка, и это является причиной того, что отладочные версии библиотеки заполняют память специальными шаблонами для ускорения обнаружения такого рода ошибок (например, если ваш ' page_number' вдруг становится 3735928559, остальная часть программы, надеюсь, будет разбиваться раньше). – 6502