C ++ delete [] - как проверить, "удалено ли все"? - PullRequest
0 голосов
/ 22 марта 2012

Мне было интересно, что во всей программе я использую множество char* указателей на cstrings и других указателей. Я хочу убедиться, что я удалил все указатели после завершения программы, хотя Visual Studio и Code Blocks оба делают это для меня (я думаю ..).

Есть ли способ проверить, очищена ли вся память? Что ничто еще не использует память?

Ответы [ 6 ]

3 голосов
/ 22 марта 2012

Очевидный ответ на Linux будет valgrind, но упоминание VS заставляет меня думать, что вы на Windows. Здесь - это SO поток, обсуждающий альтернативы valgrind для windows.

1 голос
/ 22 марта 2012

Visual Studio является IDE.Это даже не там, когда ваш код развернут.Он не освобождает память для вас.

Для того, что вы хотите, вы можете посмотреть на такие инструменты:

1 голос
/ 22 марта 2012

Мне было интересно, что во всей программе я использую множество char * указателей на cstrings

Почему?Я пишу код на C ++ каждый день и вообще очень редко использую указатель.На самом деле это только при использовании сторонних API, и даже тогда я могу в некоторой степени обойти это.Не то, чтобы указатели изначально были плохими, но если вы можете избежать их, сделайте это, поскольку это упрощает вашу программу.

Я хочу убедиться, что я удалил все указатели после того, как программа завершена

Это немного бессмысленное упражнение.ОС сделает это за вас, когда очистит ваш процесс.

0 голосов
/ 22 марта 2012

Если это специфично для Windows, вы можете вызвать это в начале вашей программы: -

_CrtSetDbgFlag(_crtDbgFlag | _CRTDBG_LEAK_CHECK_DF);

После включения

#include <crtdbg.h>

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

Обратите внимание, что это происходит только в сборках DEBUG, в сборках RELEASE код ничего не делает (что является вероятнымчто хочешь в любом случае)

0 голосов
/ 22 марта 2012

Если вы не пишете код драйвера, вы абсолютно ничего не можете сделать с памятью, выделенной в куче / свободном хранилище, которая могла бы вызвать утечку после завершения программы. Утечка памяти является проблемой только в течение жизни данного процесса; как только конкретный процесс пропустил все свое адресное пространство, он больше не может получить процесс _that_particular_.

И не ваш компилятор выполняет полную очистку, а ОС. Во всех современных операционных системах, которые поддерживают сегрегированные адресные пространства процессов (т. Е. В которых один процесс не может читать / записывать адресное пространство другого процесса, по крайней мере, без помощи ОС), когда программа завершается, все адресное пространство процесса освобождается ОС, независимо от того, имеет ли программа чистую функцию free () или удалила всю память, выделенную для кучи / freestore. Вы можете легко проверить это: Напишите программу, которая выделяет 256 МБ пространства, а затем либо завершает работу, либо возвращается нормально, не освобождая / не удаляя выделенную память. Затем запустите вашу программу 16 раз (или больше). Стреляй, запусти 1000 раз. Если выход без освобождения этой памяти приводил к ее забвению до перезагрузки, вам очень скоро не хватит доступной памяти. Вы обнаружите, что это не так.

Эта же небрежность неприемлема для некоторых других типов памяти, однако: если ваша программа удерживает какие-либо «дескрипторы» (число, которое идентифицирует какой-то ресурс, предоставленный процессу операционной системой), в некоторых случаях если вы выйдете из программы ненормально или нечисто, не отпустив дескрипторы, они останутся утерянными до следующей перезагрузки. Но если ваша программа не вызывает функции ОС, которые предоставляют вам такие дескрипторы, это все равно не проблема.

0 голосов
/ 22 марта 2012

Возможно, вы захотите использовать какой-нибудь интеллектуальный указатель (см., Например, библиотеку Boost ).Идея состоит в том, что вместо того, чтобы управлять памятью вручную (то есть вызывать удаление явно, когда вам больше не нужен объект), вы используете RAII , чтобы выполнить эту работу за вас.

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

RAII в C ++ использует тот факт, что деструктор объекта, выделенного из стека, вызывается автоматически, когда этот объект выходит из области видимости.Если логика деструктора написана правильно, последним объектом, который ссылается (управляет) на динамически распределяемые данные, будет тот (и только один), который освобождает эту память.Этого можно достичь путем подсчета ссылок, ведения списка ссылок и т. Д.

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

...