Crray не освобождает память - PullRequest
3 голосов
/ 18 ноября 2011

У меня очень простая проблема, и я, кажется, озадачен тем, что происходит.Посмотрите на следующий код:

CArray<double, double&> arr;
arr.SetSize(50000);

for(int i =0; i< 50000; i++)
{
    arr[i] = (i+2)*3.14f;
}

arr.RemoveAll();

Я бы предположил, что после RemoveAll() память будет освобождена, но, похоже, этого не происходит.Чтобы проверить объем памяти, откройте Taskmanager и просмотрите память вашего exe-файла.Увеличивается при вызове arr.SetSize(), но никогда не уменьшается даже тогда, когда этот arr выходит из области видимости.Может кто-нибудь пролить свет на это?

Ответы [ 3 ]

7 голосов
/ 18 ноября 2011

Первое, что нужно:

Диспетчер задач! = Профилировщик памяти

Операционная система (или, точнее, система времени выполнения C), безусловно, кеширует часть памяти, которую выallocate.

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

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

Второе:

Как и все не глупые классы динамических массивов, CArray не освобождаетпамять, поддерживающая массив, даже когда вы удаляете все элементы на случай, если вам понадобится снова использовать буфер памяти.Было бы ужасной тратой процессорных циклов удалить базовый буфер памяти только для того, чтобы обнаружить, что вам нужно потратить еще больше процессорных циклов для перераспределения другого буфера для обработки вашего следующего вызова CArray::Append(), который может прийти сразу после CArray::RemoveAll().

Если вы действительно хотите избавиться от этого дополнительного пространства, используйте CArray :: FreeExtra () .Обратите внимание, что функция может включать выделение нового буфера и копирование элементов в новый, а затем удаление старого буфера.

2 голосов
/ 18 ноября 2011

Как говорили другие, RemoveAll не освобождает память, выделенную CArray, вам нужно вызвать CArray :: FreeExtra.

Вы сказали, что память не выходит из строя после деструктора CArray.CArray :: SetSize выделяет память из кучи, деструктор CArray освобождает ее.Но это не означает, что динамическая память возвращается операционной системе.

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

1 голос
/ 18 ноября 2011

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

...