Как игнорировать ложные положительные утечки памяти из _CrtDumpMemoryLeaks? - PullRequest
10 голосов
/ 24 февраля 2010

Кажется, всякий раз, когда есть статические объекты, _CrtDumpMemoryLeaks возвращает ложное срабатывание, утверждая, что это утечка памяти. Я знаю, что это потому, что они не уничтожаются до тех пор, пока не завершится функция main () (или WinMain). Но есть ли способ избежать этого? Я использую VS2008.

Ответы [ 7 ]

11 голосов
/ 11 марта 2011

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

Добавьте следующую строку вместо вызова _CrtDumpMemoryLeaks где-то в начале main ():

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

Подробнее об использовании и макросах см. В статье MSDN:

http://msdn.microsoft.com/en-us/library/5at7yxcs(v=vs.71).aspx

1 голос
/ 16 апреля 2019

Старый вопрос, но у меня есть ответ. Я могу разбить отчет на ложные срабатывания и реальные утечки памяти. В своей основной функции я инициализирую отладку памяти и вырабатываю реальную утечку памяти в самом начале моего приложения (никогда не удаляйте pcDynamicHeapStart):

int main()
{   
   _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
   char* pcDynamicHeapStart = new char[ 17u ];
   strcpy_s( pcDynamicHeapStart, 17u, "DynamicHeapStart" );

   ...

После того, как моя заявка будет завершена, отчет содержит

Detected memory leaks!
Dumping objects ->
{15554} normal block at 0x00000000009CB7C0, 80 bytes long.
Data: <                > DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD
{14006} normal block at 0x00000000009CB360, 17 bytes long.
Data: <DynamicHeapStart> 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74 
{13998} normal block at 0x00000000009BF4B0, 32 bytes long.
Data: < ^              > E0 5E 9B 00 00 00 00 00 F0 7F 9C 00 00 00 00 00 
{13997} normal block at 0x00000000009CA4B0, 8 bytes long.
Data: <        > 14 00 00 00 00 00 00 00 
{13982} normal block at 0x00000000009CB7C0, 16 bytes long.
Data: <   @            > D0 DD D6 40 01 00 00 00 90 08 9C 00 00 00 00 00

...

Object dump complete.

Теперь посмотрите на строку "Данные: <<strong> DynamicHeapStart > 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74".

Все приведенные ниже утечки репортеров являются ложными срабатываниями, все вышеперечисленные являются настоящими утечками. Ложные срабатывания не означают, что утечки нет (это может быть статически связанная библиотека, которая выделяет кучу при запуске и никогда не освобождает ее), но вы не можете устранить утечку, и это не проблема.

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

1 голос
/ 08 апреля 2010

1) Вы сказали:

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

Я не думаю, что это правильно. РЕДАКТИРОВАТЬ: Статические объекты не создаются в куче. END EDIT: _CrtDumpMemoryLeaks охватывает только память кучи crt. Поэтому эти объекты не должны возвращать ложные срабатывания. Тем не менее, это другое дело, если статические переменные являются объектами, которые сами содержат некоторую кучную память (если, например, они динамически создают объекты-члены с operator new()).

2) Рассмотрите возможность использования _CRTDBG_LEAK_CHECK_DF для активации проверки утечки памяти в конце выполнения программы (это описано здесь: http://msdn.microsoft.com/en-us/library/d41t22sb(VS.80).aspx). Я полагаю, что тогда проверка утечки памяти выполняется даже после завершения статических переменных.

1 голос
/ 24 февраля 2010

Не прямое решение, но в целом я считаю целесообразным переместить как можно больше распределения из статического времени инициализации. Обычно это приводит к головным болям (порядок инициализации, порядок деинициализации и т. Д.).

Если это оказывается слишком сложным, вы можете позвонить _CrtMemCheckpoint (http://msdn.microsoft.com/en-us/library/h3z85t43%28VS.80%29.aspx) в начале main() и _CrtMemDumpAllObjectsSince в конце.

0 голосов
/ 22 мая 2019

Я могу порекомендовать Visual Leak Detector (это бесплатно), а не использовать вещи, встроенные в VS. Моя проблема заключалась в использовании _CrtDumpMemoryLeaks с библиотекой с открытым исходным кодом, которая создала 990 строк вывода, насколько я могу судить, со всеми ложными срабатываниями, а также с некоторыми улучшениями. VLD проигнорировал их и правильно сообщил о некоторых утечках, которые я добавил для тестирования, в том числе в нативной DLL, вызываемой из C #.

0 голосов
/ 10 августа 2010

Ach. Если вы уверены, что _CrtDumpMemoryLeaks() лжет, то вы, вероятно, правы. Большинство предполагаемых утечек памяти, которые я вижу, связаны с неправильными вызовами _CrtDumpMemoryLeaks(). Я полностью согласен со следующим; _CrtDumpMemoryLeaks() сбрасывает все открытые ручки. Но ваша программа, вероятно, уже имеет открытые дескрипторы, поэтому обязательно вызывайте _CrtDumpMemoryLeaks() только после того, как все дескрипторы будут освобождены. См. http://www.scottleckie.com/2010/08/_crtdumpmemoryleaks-and-related-fun/ для получения дополнительной информации.

0 голосов
/ 24 февраля 2010

Можете ли вы сделать снимок выделенных в данный момент объектов каждый раз, когда вам нужен список? Если это так, вы можете удалить изначально выделенные объекты из списка, когда вы ищете утечки, возникающие в процессе работы. В прошлом я использовал это, чтобы найти дополнительные утечки.

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

Jacob

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...