FastMM сообщает об утечках памяти в контейнерах STL в C ++ Builder 6

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

Например, если я создаю std::vector<int> в main():

std::vector<int> v;

Скомпилируйте, запустите и закройте, утечек нет.

Если я сделаю:

std::vector<int> v;
v.push_back(100);

Я получил:

Это приложение утекло память. Небольшие утечки блока:

309 — 340 байтов: неизвестно x 1

Точно так же я получаю сообщение об утечке:

std::vector<int> v;
v.push_back(100);
v.clear();

А также сообщается об утечке:

std::vector<int> v;
v.reserve(1);

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

Кто-нибудь может объяснить, что происходит? Я использую Borland C ++ Builder 6 и FastMM4. Я менял различные настройки в FastMMOptions.incТем не менее, я все еще вижу эти утечки сообщили.

0

Решение

Очистка std::vector не освобождает память, используемую для vectorвнутренний массив, он просто разрушает элементы внутри массива, а затем устанавливает std::vector::size() в 0. Сам массив все еще выделен, поэтому его можно использовать для новых элементов, помещенных в vector, vectorдеструктор освободит массив.

В C ++ Builder 6 библиотека STL по умолчанию — STLPort (заменена на Dinkumware в C ++ Builder 2006). STLPort реализация ~std::vector() просто уничтожает элементы массива (как будто clear() был вызван), но не освобождает сам массив, таким образом, «утечка» вы видите. Что на самом деле не является утечкой, согласно следующему FAQ на веб-сайте STLPort:

В6.2 Мой инструмент обнаруживает утечки памяти в приложении с STLport. Это утечка из STLport?

A6.2 В большинстве случаев это «утечки псевдопамяти», которые некоторые инструменты ошибочно поддерживают.

В компиляции по умолчанию STLport распределитель узлов используется для выделения внутренней памяти. Распределитель узлов работает путем предварительного выделения большого куска памяти и раздачи небольших блоков памяти. Блок памяти не освобождается при запуске приложения, использующего STLport (то есть он не возвращается в систему. Существуют такие инструменты, как BoundsChecker, Purify или Valgrind, которые проверяют утечки memorytml, память, которая не освобождается, когда она больше не используется. Эти инструменты могут сообщать о ложных утечках памяти, когда используется распределитель узлов STLport. Блок памяти обычно освобождается в конце приложения, но контролеры памяти обычно сообщают об утечках памяти до этого момента. Другая проблема с памятью может появиться при использовании общих библиотек (например, DLL, эта проблема характерна для модели Windows DLL), которые используют STLport для внутреннего использования и статически связаны с ним. Если память распределена в dll и освобождена в другом, то распределитель узла STLport сохранит освобожденную память для будущего использования. Если вы не используете эту память, то глобальное потребление памяти вашим приложением будет расти до тех пор, пока не произойдет сбой приложения, даже если в действительности не будет утечки памяти. Вот почему вы всегда должны использовать согласованную конфигурацию всего в dll или всего в статической lib.

Существуют способы устранения утечек псевдопамяти (так как в конце программы память освобождается должным образом, утечки являются просто псевдослучайными). Вы можете использовать другой распределитель, который используется в STLport. Открыть файл "stlport/stl/_site_config.h" и раскомментируйте одно из следующего:

_STLP_USE_NEWALLOC   enables a simple allocator that uses "new/delete"_STLP_USE_MALLOC     enables a simple allocator that uses "malloc/free"

Распределитель new / delete обладает тем преимуществом, что дает точку входа для отслеживания нехватки памяти. Для получения дополнительной информации см. Set_new_handler в документации по компилятору или в стандарте C ++.

В качестве альтернативы вы можете определить следующий символ, просто раскомментируйте его в "stlport/stl/_site_config.h",

_STLP_LEAKS_PEDANTIC

Символ заставляет освободить все фрагменты памяти. Также смотрите комментарии вокруг символа в файле конфигурации.

Обратите внимание, что вы должны перекомпилировать STLport и ваше приложение, а также все зависимые от вас библиотеки, если вы внесете какие-либо изменения в файл!

Есть также некоторые определения, которые помогают в отладке проблем с памятью в STLport. В режиме _STLP_DEBUG также определите следующие символы, либо в «./stlport/stl_user_config.h», либо в настройках вашего проекта:

_STLP_DEBUG_ALLOC
_STLP_DEBUG_UNINITIALIZED

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

Тем не менее, RogueWave STL, который использовался в более ранних версиях C ++ Builder, также поставляется с C ++ Builder 6 для обратной совместимости со старым кодом и не страдает от этой проблемы. Вы можете переключиться с STLPort на RogueWave, определив _USE_OLD_RW_STL в списке условий вашего проекта.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]