Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблемы с памятью и созданием переменных

389
08 января 2004 года
Dmitri
69 / / 20.08.2000
Добрый день! Подскажите, пожалуйста, почему моя программа постепенно (чем больше я вызываю главную расчетную функцию, тем быстрее) забивает оперативную память все больше и больше (от 4 Mb до 30 Mb)?

Суть расчетной функции такова: выделяется память под более 100 динамических массивов с 3000 элементами в каждом
 
Код:
float* a1 = new float[3000];

// ...

float* a120 = new float[3000];

В конце функции я все эти массивы удаляю
 
Код:
delete [] a1;

// ...

delete [] a120;

Но, помимо этого, в функции каждый раз при ее запуске я объявляю более 500 переменных типа float и double. Не происходит ли при этом переполнение стека или что-нибудь подобное?

Вообще, где можно почитать про выделение памяти, стек и т. д.?

И что делать в моей ситуации, чтобы не "забивать" память настолько, а переменные-то нужны, и все 500?
1.9K
08 января 2004 года
AviDen
91 / / 26.12.2003
Пару моментов.

Во-первых, весь код начиная сразу после оператора выделения памяти и до оператора освобождения этого же участка памяти рекомендуется заключать в Try..Finally, т.е.:

 
Код:
float* a1 = new float[3000];
try
  <body>
finally
  delete [] a1;
end


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

Во-вторых, если все 500 переменных ты обявляешь статически, то дела действительно плохи. Это ты действительно загнул.:( Попробуй их тоже держать в массиве (или массивах).

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

Ну, и наконец проверь код в самой проце - может, там чегой-то не так?
389
08 января 2004 года
Dmitri
69 / / 20.08.2000
В смысле в массиве? Это не удобно. Может, их просто тоже создавать динамически типа

float* abc = new float;

Или так не пойдет?
2.0K
08 января 2004 года
Fazil6
126 / / 17.12.2003
Если все так как ты описал в вопросе, то память у тебя уходит не при выделении под массивы.
1. насколько я понял в конце ф-ции ты многократно вызываешь delete . Может ты пропустил удаление какого-нить массива.
2. может быть у тебя происходит преждевременный выход из этой функции и код в конце не всегда выполняется? (решение этого тебе уже подсказал AviDen try...finally)
3. что вообще происходит в функции, что она делает и какие другие функции вызывает? Вызывается ли эта функция по какому-нить событию (обработчик ли это)? Да и мало ли что может быть еще...
4.нет ли у тебя в коде переполнения твоих массивов?
389
08 января 2004 года
Dmitri
69 / / 20.08.2000
2 AviDen:

Цитата:
Во-вторых, если все 500 переменных ты обявляешь статически, то дела действительно плохи. Это ты действительно загнул. Попробуй их тоже держать в массиве (или массивах).



А что плохого в том, что я выделяю память под 500 переменных типа float??? Это же не DOS, за раз памяти я выделяю всего 4*500*3000 = 7 Mb. Насколько я понимаю, при статическом выделении памяти под переменные (как в данном случае) после выхода из расчетной функции эта память ДОЛЖНА освобождаться. Но, по-видимому, она _почему-то_ НЕ освобождается... Но почему? Или я что-то неправильно понимаю?

В функции НЕТ никаких операций с памятью! НИКАКИХ realloc, malloc и прочих! Никаких new, delete!


Цитата:
возникало бы исключение StackOverflow



Да, такое было, пока в расчетах я не поменял тип некототрых переменных с float на double. Но в данном случае, действительно, ошибка не в этом.


Цитата:
Ну, и наконец проверь код в самой проце - может, там чегой-то не так?



А что там может быть не так? Функция большая, поэтому приведу примерную ее структуру:

Код:
// Объявление около 300 переменных 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:

Цитата:
Если все так как ты описал в вопросе, то память у тебя уходит не при выделении под массивы.



Именно! Я сам понял, что массивы тут ни при чем. Дело в СТАТИЧЕСКИХ переменных. Но почему?


Цитата:
1. насколько я понял в конце ф-ции ты многократно вызываешь delete . Может ты пропустил удаление какого-нить массива.



Нет, я точно все проверил - сколько создаю, столько и удаляю.

ПРИЧЕМ, ВНИМАНИЕ: если смотреть в TaskManager при работе проги, память увеличивается в течение всего ее расчета. А расчет состоит из начальных динамических объявлений и !!! 3000 БОЛЬШИХ циклов !!! Так вот, с каждым циклом (это видно) забивается память и при завершении расчетов очищается всего килобайт 30-100 (при том, что прога отжирает при одном расчете около 10-15 Mb).

Но почему после каждого цикла память, выделенная под статические переменные, НЕ отдается обратно???


Цитата:
2. может быть у тебя происходит преждевременный выход из этой функции и код в конце не всегда выполняется? (решение этого тебе уже подсказал AviDen try...finally)



Нет, дело не в этом. См. п.1. try-finally пробовал, все равно также все.


Цитата:
3. что вообще происходит в функции, что она делает и какие другие функции вызывает? Вызывается ли эта функция по какому-нить событию (обработчик ли это)? Да и мало ли что может быть еще...



См. мой ответ AviDen'у в этом же посте повыше. Там написано все, что делает функция. Вызывается по onClick().


Цитата:
4.нет ли у тебя в коде переполнения твоих массивов?



Вроде бы нет. Циклов 3000, а массивы создаются на 3001 элементов (на всякий случай). Да, и как, я уже выяснил (читай выше), дело не в динамически объвленных массивах, а в статических переменных, которые я объявляю в каждом цикле...

310
08 января 2004 года
fellow
853 / / 17.03.2003
Чтобы отследить утечку памяти, включите в опциях проекта (через соответствующий диалог) CodeGuard. В этом случае Вы получите информацию о всех случаях утечки памяти, с указанием последовательности операций и номерами строк исходного текста. Тогда и будете решать, что именно не так, что именно нужно менять. Ну а насчёт try....finally коллега AviDen прав.
3.8K
13 января 2004 года
ILSOR
25 / / 03.12.2003
Цитата:
Originally posted by Dmitri
Добрый день! Подскажите, пожалуйста, почему моя программа постепенно (чем больше я вызываю главную расчетную функцию, тем быстрее) забивает оперативную память все больше и больше (от 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

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог