Неинициализированные блоки памяти в VC ++ - PullRequest
5 голосов
/ 15 сентября 2008

Как всем известно, среда выполнения Visual C ++ помечает неинициализированные или просто освобожденные блоки памяти специальными ненулевыми маркерами. Есть ли способ полностью отключить это поведение, не устанавливая вручную всю неинициализированную память в нули? Это вызывает хаос с моими действительными ненулевыми проверками, так как 0xFEEEFEEE != 0.

Хм, возможно, мне следует объяснить немного лучше. Я создаю и инициализирую переменную (через new), и все это идет отлично. Когда я освобождаю его (с помощью удаления), он устанавливает указатель на 0xFEEEFEEE вместо NULL. Когда я вставляю правильную проверку для NULL, как должны делать все хорошие программы, которые управляют собственной памятью, я сталкиваюсь с проблемами, когда 0xFEEEFEEE проходит проверку NULL без проблем. Есть ли хороший способ, кроме ручной установки всех указателей на NULL при их удалении, определить, когда память уже была освобождена? Я бы предпочел не использовать Boost просто потому, что я не хочу накладных расходов, хотя они могут быть небольшими, поскольку это единственное, для чего я буду использовать Boost.

Ответы [ 15 ]

1 голос
/ 17 сентября 2008

@ [Джефф Хаббард]:

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

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

Подпись 0xFEEEFEEE используется диспетчером кучи ОС для обозначения освобожденной памяти (см. http://www.nobugs.org/developer/win32/debug_crt_heap.html).. Можете ли вы случайно опубликовать некоторый код репро и указать, какую именно версию компилятора вы используете?

0 голосов
/ 23 сентября 2014

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

0 голосов
/ 16 сентября 2008

Почему бы не создать свой собственный #define и не привыкнуть его использовать?

* 1003 Т.е. *

#define SafeDelete(mem) { delete mem; mem = NULL; }
#define SafeDeleteArray(mem) { delete [] mem; mem = NULL; }

Очевидно, вы можете назвать это как угодно. deleteZ, deletesafe, все, что вам удобно.

0 голосов
/ 16 сентября 2008

если вы используете malloc, он не инициализирует память ни к чему. вы получите что угодно. если вы хотите выделить блок и инициализировать его 0, используйте 'calloc', который похож на malloc только с инициализацией (параметр размера элемента, который вы устанавливаете в 1, если вы хотите эмулировать malloc). Вы должны прочитать Calloc перед его использованием, поскольку у него есть небольшие отличия.

http://wiki.answers.com/Q/What_is_the_difference_between_malloc_and_calloc_functions

0 голосов
/ 15 сентября 2008

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

Лучше всего просто привыкнуть устанавливать их в 0, это всего лишь 2 дополнительных символа.

int *ptr=0;

Вы также можете использовать макрос NULL, который определен как 0 (но не по умолчанию, поэтому будьте осторожны с несколькими определениями, когда включаете такие вещи, как windows.h и определяете его сами!

...