Проблемы с памятью и созданием переменных
Суть расчетной функции такова: выделяется память под более 100 динамических массивов с 3000 элементами в каждом
// ...
float* a120 = new float[3000];
В конце функции я все эти массивы удаляю
// ...
delete [] a120;
Но, помимо этого, в функции каждый раз при ее запуске я объявляю более 500 переменных типа float и double. Не происходит ли при этом переполнение стека или что-нибудь подобное?
Вообще, где можно почитать про выделение памяти, стек и т. д.?
И что делать в моей ситуации, чтобы не "забивать" память настолько, а переменные-то нужны, и все 500?
Во-первых, весь код начиная сразу после оператора выделения памяти и до оператора освобождения этого же участка памяти рекомендуется заключать в Try..Finally, т.е.:
try
<body>
finally
delete [] a1;
end
Вложенные выделения памяти оформляются аналогично. Это позволит тебе освобождать память в любом случае, даже если ты завершаешь функцию ДО освобождения памяти или происходит исключение.
Во-вторых, если все 500 переменных ты обявляешь статически, то дела действительно плохи. Это ты действительно загнул.:( Попробуй их тоже держать в массиве (или массивах).
А стек здесь наверное не при чем. По крайней мере, если бы происходило его переполнение, то у тебя или возникало бы исключение StackOverflow (если в опциях компилера включена проверка стека), или же прога просто бы "вылетала".
Ну, и наконец проверь код в самой проце - может, там чегой-то не так?
float* abc = new float;
Или так не пойдет?
1. насколько я понял в конце ф-ции ты многократно вызываешь delete . Может ты пропустил удаление какого-нить массива.
2. может быть у тебя происходит преждевременный выход из этой функции и код в конце не всегда выполняется? (решение этого тебе уже подсказал AviDen try...finally)
3. что вообще происходит в функции, что она делает и какие другие функции вызывает? Вызывается ли эта функция по какому-нить событию (обработчик ли это)? Да и мало ли что может быть еще...
4.нет ли у тебя в коде переполнения твоих массивов?
А что плохого в том, что я выделяю память под 500 переменных типа float??? Это же не DOS, за раз памяти я выделяю всего 4*500*3000 = 7 Mb. Насколько я понимаю, при статическом выделении памяти под переменные (как в данном случае) после выхода из расчетной функции эта память ДОЛЖНА освобождаться. Но, по-видимому, она _почему-то_ НЕ освобождается... Но почему? Или я что-то неправильно понимаю?
В функции НЕТ никаких операций с памятью! НИКАКИХ realloc, malloc и прочих! Никаких new, delete!
Да, такое было, пока в расчетах я не поменял тип некототрых переменных с float на double. Но в данном случае, действительно, ошибка не в этом.
А что там может быть не так? Функция большая, поэтому приведу примерную ее структуру:
// Вообще объявление переменных разбросано по всей
// функции
float a=10.0, b=57.3 ,c=0;
// Линейные расчеты
a=pow(b,c)*sqrt(4035)/47+9;
// Цикл for на 3000 шагов
// В нем дофига линейных расчетов с примесью
// if-else и while
Самое главное, как я уже говорил, НЕТ никаких операций с памятью! НИКАКИХ realloc, malloc и прочих! Никаких new, delete!
new-delete используется только в САМОМ начале и САМОМ конце и корретно работает (даже с try-finally). Т.е., дело не в динамическом объявлении переменных.
2 Fazil6:
Именно! Я сам понял, что массивы тут ни при чем. Дело в СТАТИЧЕСКИХ переменных. Но почему?
Нет, я точно все проверил - сколько создаю, столько и удаляю.
ПРИЧЕМ, ВНИМАНИЕ: если смотреть в TaskManager при работе проги, память увеличивается в течение всего ее расчета. А расчет состоит из начальных динамических объявлений и !!! 3000 БОЛЬШИХ циклов !!! Так вот, с каждым циклом (это видно) забивается память и при завершении расчетов очищается всего килобайт 30-100 (при том, что прога отжирает при одном расчете около 10-15 Mb).
Но почему после каждого цикла память, выделенная под статические переменные, НЕ отдается обратно???
Нет, дело не в этом. См. п.1. try-finally пробовал, все равно также все.
См. мой ответ AviDen'у в этом же посте повыше. Там написано все, что делает функция. Вызывается по onClick().
Вроде бы нет. Циклов 3000, а массивы создаются на 3001 элементов (на всякий случай). Да, и как, я уже выяснил (читай выше), дело не в динамически объвленных массивах, а в статических переменных, которые я объявляю в каждом цикле...
Добрый день! Подскажите, пожалуйста, почему моя программа постепенно (чем больше я вызываю главную расчетную функцию, тем быстрее) забивает оперативную память все больше и больше (от 4 Mb до 30 Mb)?
И что делать в моей ситуации, чтобы не "забивать" память настолько, а переменные-то нужны, и все 500?
выделять память примерно так -
#define MAS_SIZE 500
DWORD Handle=(DWORD)GetProcessHeap();
float* mas = (float*)HeapAlloc(Handle,NULL,sizeof(float)*MAS_SIZE);
использовать:
mas[sizeof(float)*index]=(float)34.23456;
а потом освободить память в любом месте проги:
HeapFree(mas);
=============================================
ПРИМЕРНО так, насчет параметров точно не помню...
Я ПИСАЛ ПОДОБНОЕ МЕСЯЦ НАЗАД - ЗДЕСЬ ВОЗМОЖНЫ
КРУПНЫЕ ОШИБКИ.Но смысл правилен ...
ВСЕ ДЕТАЛИ И ОБЬЯСНЕНИЯ В MSDN или Win32 SDK
;)
Кстати, MS VisualC++ 6 - прекрасно обнаруживает
утечки памяти, а в Билдере, как и было уже
сказано, нужен CodeGuard