Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];

Вниз

EOutOfMemory   Найти похожие ветки 

 
Е.М.   (2003-08-23 00:16) [0]

Имеется динамический массив определённого типа. При его заполнении через некоторое время возникает ошибка "Out of memory". Как решить данную проблему? Спасибо.


 
Anatoly P   (2003-08-23 00:23) [1]

При назначении размера N - максимальный номер- (N-1), может из-за этого


 
Юрий Федоров   (2003-08-23 01:24) [2]

наверно стоит поверить - действительно не хватаает памяти...
По крайней мере менеджер памяти уже не может выделить такой объем ...
приведи код


 
Е.М.   (2003-08-23 01:42) [3]

Просто я никогда раньше не сталкивался с подобной проблемой, о распределении памяти никогда не задумывался. А как же файл подкачки? Почему он не используется? Может есть какой-нибудь способ выделить дополнительную память?


 
Юрий Федоров   (2003-08-23 01:48) [4]

Если ты его заполняешь в цикле, и на каждой итерации вызываешь
SetLength(.., length(..) + 1) например, то это вполне нормальная реакиция на твои действия, потому что память не бесконечна, и она время от времени фрагментируется.
А при заполнении массива, под который уже выделена память такая ситуация вряд ли возможна.
В общем (еще раз) приведи код


 
Marser   (2003-08-23 01:56) [5]

{$M+}


 
Е.М.   (2003-08-23 11:20) [6]

Юрий, именно так я и делаю.

procedure frmMain.ReadClubs;
var
ClubFile: file of TClub;
Clubs: array of TClub;
Index: Integer;
begin
Index := 0;
AssignFile(ClubFile, "clubs.dat");
Reset(ClubFile);
repeat
begin
Read(ClubFile, Club);
SetLength(Clubs, Length(Clubs) + 1);
Clubs[Index] := Club;
inc(Index);
end
until Eof(ClubFile);
CloseFile(ClubFile);
end;

Тогда каким образом можно выделить память под массив? Или может есть другой способ реализации данной процедуры?
TClub - содержит различные типы данных, переменная этого типа занимает около 30 кб.
Marser, можно поподробней, что происходит при использовании данной директивы, и каким образом её можно использовать в приведённом коде.
Спасибо.


 
kostas   (2003-08-23 12:26) [7]

Сначала прочитай файл - посчитай сколько записей в твоем файле, следующим шагом установи Размер твоего массива и опять в цикле заполняй, читая значения из файла! По расходу памяти это намного дешевле, поверь!


 
Romkin   (2003-08-23 13:01) [8]

ДА даже считать не надо - количество записей равно размеру файла / sizeOf(TClub)
И все. А происходит следующее: у тебя на SetLength выделяется блок памяти на 1 TClub больше прежнего, затем туда копируются данные из прежнего массива, потом он уничтожается и переменной присваивается новый адрес. Не много ли действий?


 
Palladin   (2003-08-23 13:08) [9]

вообщето существует функция FileSize


 
Е.М.   (2003-08-23 15:50) [10]

Kostas и Romkin, большое вам спасибо. Я, в принципе, так и собирался делать с самого начала. Но я не привёл весь код. Дело в том, что эта процедура служит не только для чтения данных из файла, но и для импортирования данных в ранее заполненный массив. Промежуточная переменная Club мне необходима для проверки наличия такой переменной в массиве. У каждой переменной типа TClub существует уникальный номер (Club.UniqueID: Integer). При заполнении массива происходит проверка на наличие в массиве переменной с таким ID, и если такая присутствует, то Index присваивается её порядковый номер в массиве. Если же отсутствует, тогда уже происходит удлиннение массива на единицу, а Index присваивается Length(Clubs) - 1.

Т.о. проблему решить можно следующим образом. Для чтения использовать алгоритм, предложенный Kostas"ом. Что же касается импорта, нужно:
Аналогичным образом загружать данные из импортирумого файла во второй массив (пусть будет ImportClubs), затем анализировать оба массива на наличие переменных с одинаковым UniqueID, а уже потом увеличивать длину основного массива на (Length(ImportClubs) - "количество совпавших UniqueID". И переносить данные из второго массива в первый.
Хотя сдаётся мне, что это не самый лучший способ. Может быть существуют иные варианты? Спасибо.

P.S. Каким способом эффективнее всего производить проверку на наличие в массиве переменной с данным UniqueID?
Я делаю так:
function GetClubIndex(UniqueID: Integer): Integer;
var
i: Integer;
begin
Result := -1;
i := -1;
repeat inc(i)
until (Clubs[i].UniqueID = UniqueID) or (i = Length(Clubs) - 1);
if Clubs[i].UniqueID = UniqueID then Result := i;
end;
end;


 
Е.М.   (2003-08-23 16:09) [11]

To Palladin
Я, впрочем как и другие, думал что FileSize - непосредственно размер файла, а не количество переменных данного типа в файле.
Спасибо.


 
Е.М.   (2003-08-23 16:09) [12]

To Palladin
Я, впрочем как и другие, думал что FileSize - непосредственно размер файла, а не количество переменных данного типа в файле.
Спасибо.


 
Anatoly Podgoretsky   (2003-08-23 16:38) [13]

Если у тебя есть N единиц, весом по 30К, а вес партии 390К, то сколько единиц в партии?
Извини, что приходится задавать задачку из начальной школы, но все таки попробуй ее решить.


 
Е.М.   (2003-08-23 16:50) [14]

Anatoly Podgoretsky, не понял к чему это...
Внимательно прочитайте текст выше.


 
Е.М.   (2003-08-23 16:50) [15]

Anatoly Podgoretsky, не понял к чему это...
Внимательно прочитайте текст выше. Речь совсем не об этом...


 
Anatoly Podgoretsky   (2003-08-23 16:54) [16]

Очень внимательно прочитал и задачку не снимаю.


 
Anatoly Podgoretsky   (2003-08-23 16:55) [17]

Кстати тогда о чем речь? Раз уж заикнулся.


 
Palladin   (2003-08-23 22:19) [18]


> Е.М. (23.08.03 16:50) [15]

Скажу по другому
У тебя есть высота кирпича и количество кирпичей в доме по вертикали... сможешь ли ты сказать какой высоты дом?


 
Anatoly Podgoretsky   (2003-08-23 22:48) [19]

А наоборот, если известна высота дома (размер файла) и высота одного кирпичам (размер записи) можно узнать количество кирпичей (записей) при условии, что человек закончил начальную школу (первые четыре класса)? Мне кажется что делить и умножать умеют еще до школы, у нас это проходят при дошкольном образовании?


 
Е.М.   (2003-08-24 01:46) [20]

Palladin и Anatoly Podgoretsky, я конечно благодарен вам в столь подробном освещении абсолютно не относящейся к основной теме вопросу (скорее побочному вопросу, который был решён Palladin"ом одним единственным словом - FileSize).
Но хочу акценитровать своё (и главное - ваше) внимание не на "кирпичиках" и "начальной школе", а на алгоритме работы процедуры, описанной в 10-м ( !) сообщении. Т.е. требуется сравнивать данные из нового файла с содержимым массива, и в случае совпадения у этих данных UniqueID, не добавлять его в массив, а замещать прежнее. Надеюсь, понятно выразился.

И если вы всё же постараетесь поднапрячься и вникнуть в то, о чём повествуется в 10-м сообщении, то поймёте, что проблема состоит соовсем не в том, чтобы узнать "количество кирпичиков" (для этого как раз и существует ф-я FileSize - "количество кирпичиков" :)).

Ладно, обьясню "кирпичным" языком. Есть два дома, состоящих из кирпичиков одинаковых габаритов. На каждом из кирпичиков стоит номер, причём два любых кирпичика одного и того же дома не могут иметь одинаковые номера (UniqueID). Но эти номера могут совпадать у кирпичиков из разных домов. Задача - построить новый дом из двух данных на основе первого, причём в новом, большом домике, не должно также быть двух кирпичиков с одинаковыми номерами. Также следует принимать во внимание и тот факт, что кирпичики из второго дома имеют приоритет перед кирпичиками первого дома. Т.е. если дяденька строитель берёт кирпичик со второго дома, но обнаруживает аналогичный в первом - первый должен быть ликвидирован и замещён кирпичиком из второго дома. При этом высота домика не изменяется, а лишь увеличивается на одну единичку в случае, если кирпичик из второго дома отсутствует в первом.
Дяденьке-строителю при изменении высоты дома нужно бежать за новой порцией раствора. Проблемка же в подобном строительстве заключается в том, что если дяденька будет постоянно изменять высоту на одну единичку, то он быстро исчерпает свои ресурсы, т.к. задолбается бегать за раствором. Ему ведь гораздо проще проанализировать оба дома на наличие кирпичей с одинаковыми номерами, вычислить новую высоту дома, и сразу сгонять и взять необходимое количество раствора. И уже после этого продолжить строительство.
Так вот, строителю очень нужна помощь в определении новой высоты дома. ;)


 
Anatoly Podgoretsky   (2003-08-24 11:21) [21]

Е.М. (24.08.03 01:46) [20]
Что бы не предъявлять подобного рода претензии, надо было задавать этот вопрос в отдельной ветке или уже мириться с тем, что тебе на него отвечают. По крайней мере это очень невежливо задать вопрос и предъявлять теперь претенции. Надо писать сразу - на этот вопрос прошу не отвечать!


 
Anatoly Podgoretsky   (2003-08-24 11:29) [22]

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

Успех оптимальных по ресурсам и скорости программ находится в оптимальных алгоритмах, а у нас часто строят дом не имея чертежей, а потом удивляются почему домик падает.


 
Anatoly Podgoretsky   (2003-08-24 11:37) [23]

Ответ был дан не в Palladin © (23.08.03 13:08) [9], а вRomkin © (23.08.03 13:01) [8] , в 9 только половина ответа.

Ответы по проблеме в 4, 7, 8

Задача по расчету количества кирпичей в домике связана с Е.М. (23.08.03 16:09) [11], с непоиниманием, как можно вычислить число кирпичей, зная две остальные характеристики. Функция FileSize, как раз не дает количество кирпичиков, хоть ты и продолжаешь на этом настаивать, она дает только высоту дома.
Поэтому хотелось бы, что бы ты решил задачку по определению количества кирпичиков, зная высоту дома и высоту одного кирчичика, ответы на эту задачку есть в приведенных ответах, просто жалко, что ты их не видишь.


 
Е.М.   (2003-08-24 12:11) [24]

Благодарю всех.

P.S.

FileSize function

Delphi syntax:
function FileSize( var F): Integer;

Description
In Delphi code, call FileSize to determine the size of the file specified by the file variable F. The size is expressed as the number of records in a record file.

Delphi Object and Component Library Reference ;)

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


 
Anatoly Podgoretsky   (2003-08-24 12:22) [25]

Признаю, что был неправ в отношение типизированных файлов, у меня правда немного другой хелп, Returns the size of a file in bytes or the number of records in a record file., но сути не меняет, для типизированых именно количество записей.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.018 c
1-10720
iNew
2003-08-20 05:18
2003.09.04
Копирование файлов


1-10775
pvb87
2003-08-23 19:03
2003.09.04
Linux


14-10888
Study
2003-08-14 13:15
2003.09.04
2 вопроса


1-10713
Miralex
2003-08-20 13:57
2003.09.04
Печать картинок


14-10938
sniknik
2003-08-15 01:30
2003.09.04
Не читаются CDROM в Lunix





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский