Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi
Войти
Регистрация
Восстановить пароль
 
Vabos
120 / 120 / 28
Регистрация: 12.12.2011
Сообщений: 421
#1

SetLength & EOutOfMemory - Delphi

26.10.2015, 13:45. Просмотров 496. Ответов 6
Метки нет (Все метки)

Столкнулся с такой проблемой, при заполнении динамического массива данными из xml файла (~6000 записей), получаю OutOfMemory. Чтение выполняет процедура, массив передается как var параметр. На каждый элемент массива выделяется около 400 байт (там сложная структура: записи, варианты, строки, целые и прочие числа).
Изначально длина массива = 0. Данные обрабатываю в цикле. Нахожу нужные и увеличиваю длину SetLength(A,Length(A)+1); В этом случае, примерно на 4500 элементе получаю OutOfMemory.
Нагуглил решение: сразу выделить память под максимально возможное кол-во элементов (благо это известно), а потом сократить длину массива до нужной. Все работает. К тому же, вычитал, что TList заранее выделяет память под элементы, причем с удвоением(!). В документации по SetLength имеем:
Following a call to SetLength, S is guaranteed to reference a unique string or array—that is, a string or array with a reference count of one. If there is not enough memory available to reallocate the variable, SetLength raises an EOutOfMemory exception.
Объясните пожалуйста, в чем причина такого поведения SetLength?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2015, 13:45
Я подобрал для вас темы с готовыми решениями и ответами на вопрос SetLength & EOutOfMemory (Delphi):

Как работает SetLength()
Вопрос такой: если у меня есть динамический массив dimass на n элементов я...

Incompatible types в функции SetLength
Добрый вечер. У меня в программе есть собственная функция, где применяется...

Delphi & MSSQL2K & NText - глюк!!!
Привет All. Вот в чем проблема: на сервере MSSQL 2000 валяется stored ...

Примеры работы IBX & InterBase & Delphi
Начал работать с IBX & InterBase & Delphi. может кто знает где можна найти...

Delphi&Access&logs
Добрый вечер у меня есть программка Есть форма авторизации, есть кнопка...

Acess Violation из-за SetLength
Здравствуйте, хочу сделать что-то наподобии калькулятора, и столкнулся с одной...

6
northener
пофигист широкого профиля
3251 / 2303 / 628
Регистрация: 15.07.2013
Сообщений: 13,589
26.10.2015, 13:53 #2
В фрагментации памяти. Свободной памяти может быть много, но цельного блока памяти достаточно большого размера может не быть.
1
Vabos
120 / 120 / 28
Регистрация: 12.12.2011
Сообщений: 421
26.10.2015, 14:01  [ТС] #3
Цитата Сообщение от northener Посмотреть сообщение
Свободной памяти может быть много, но цельного блока памяти достаточно большого размера может не быть.
А массив должен одним куском непрерывным лежать в памяти? Я так понял, что SetLength выделяет память под заказанную длину, а потом копирует из исходного массива элементы в новый и чистит память, выделенную под старый массив. Это с этим связано? Я думал, что массив хранится как связанный список (элемент указывает на следующий...)
0
northener
пофигист широкого профиля
3251 / 2303 / 628
Регистрация: 15.07.2013
Сообщений: 13,589
26.10.2015, 14:04 #4
Цитата Сообщение от Vabos Посмотреть сообщение
А массив должен одним куском непрерывным лежать в памяти?
Только так и никак иначе.
1
Vabos
120 / 120 / 28
Регистрация: 12.12.2011
Сообщений: 421
26.10.2015, 14:09  [ТС] #5
А есть ли какой-нибудь способ дефрагментировать память? Ну чтобы на такие вещи не нарываться? Или за правило взять, при использовании SetLength сразу запрашивать больше, чем нужно?
0
northener
пофигист широкого профиля
3251 / 2303 / 628
Регистрация: 15.07.2013
Сообщений: 13,589
26.10.2015, 14:18 #6
Цитата Сообщение от northener Посмотреть сообщение
Только так и никак иначе.
Уточнение. Это относится к статическим массивам любой размерности и к динамическим одномерным массивам.
Цитата Сообщение от Vabos Посмотреть сообщение
А есть ли какой-нибудь способ дефрагментировать память?
Специального готового инструмента для дефрагментации памяти, имхо, нет.
1
krapotkin
3295 / 2935 / 1015
Регистрация: 14.04.2014
Сообщений: 14,251
Записей в блоге: 13
27.10.2015, 08:23 #7
отказаться от динамических массивов в пользу списков
1
27.10.2015, 08:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2015, 08:23
Привет! Вот еще темы с решениями:

SetLength. Access violation
Собственно при k=19 вылазит ошибка Access violation. Не могу понять почему: ...

query='SELECT * FROM resume WHERE ' & ''' & RecSet('place')& ''' & '=' & '''& s_loc &''' & - что не так?
упростил для краткости запрос. в чем ошибка? RecSet - это коннекшн. ...

error '80020009' Îøèáêà. /lalala/profile.asp, line 28
При простейшем и сто раз работавшем скрипте, вылетает ошибка! след....

Помогите найти драйвера для pci\ven_8086&DEV_266E&SUBSYS_A002145&REV_05\3&13C0B0C5&0&F2
pci\ven_8086&DEV_266E&SUBSYS_A002145&REV_05\3&13C0B0C5&0&F2 Мультимедиа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru