![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамический массив типа Record [D6, WinXP]
Pavelkq © (2004-07-01 13:01:00)Здравствуйте! Есть задача создать массив кривой структуры:
1. Первое поле содержит всего одно число типаlongint.
2.Второе поле это динамический массив такого типа:
2.1. Типstring
2.2. Типlongint
2.3. Тип динамический массив типаstring
2.4. Тип динамический массив типаLingInt
Делаю все, как по часам:
// Создание структуры индексной таблицы (2)
Type
TIndex=record
Lema : string[50];// Пункт 2.1.
ColLem: LongInt; // Пункт 2.2.
Word : array of string[50];// Пункт 2.3.
Index : array of LongInt; // Пункт 2.4.
end;
// Создание массива индекса с полем для пункта 1.
Type TBase=Record
Sum:LongInt; // Вот он, пункт 1.
SIndex:array of TIndex;// Пункт 2 целиком.
end;
// Назначаем переменную Base вышеуказанного типа.
var Base:TBase;
Все компилируется отлично!
Далее начинаю работать с этой таблицей.
Base.Sum:=KakoyToInteger;
SetLength(Base.SIndex,Base.Sum);
...
WordI:=0;// Тип Integer
...
WordI:=WordI+1;
SetLength(Base.SIndex[N].Word,WordI);
SetLength(Base.SIndex[N].Index,WordI);
Base.SIndex[LemI].Word[N]:=Words;
Base.SIndex[LemI].Index[N]:=Int;
...
И вот при WordI=4 на выполненииSetLength(Base.SIndex[N].Index,WordI);вылетает непонятная ошибка и код в CPU.
Может быть реализовать эту структуру в другом типе. Например в баз данных?
Pavelkq (2004-07-02 07:47:00) [1]Ребята, я понял!!! Спасибо за [34] и [39]. Но особая благодарность Игорьку за [38]! Именно так и сдела.
Всем удачи!
R (2004-07-02 02:57:00) [2]В общем все уже сказано,
совет работай со строками с помощью TStringList,
дин.массив вешь хорошая, на пример - выше можно
запутаться особенно если начинается такое array of array,
да и еще в нескольких записях,
по скорости в принцепе если известен предел дин. массива
хотябы примерно ну и выдели под него сразу памяти в два раза
больше чтобы при каждом добавлении элемента не перераспределять память, а после окончательного добавления обрежь не нужную часть,
но это тоже надо делать осторожно.
Sandman25 (2004-07-01 16:29:00) [3][41] PVOzerski © (01.07.04 16:28)
Понятно.
PVOzerski (2004-07-01 16:28:00) [4]Ну, это я с учетом [33].
Sandman25 (2004-07-01 16:23:00) [5][39] PVOzerski © (01.07.04 16:20)
Не, ну нельзя так однозначно. Если память под динамический массив выделяется лишь один раз, то TList оказывается далеко позади. Особенно, если это array of integer, например.
PVOzerski (2004-07-01 16:20:00) [6]1) Короче, усвой, что указывая размер в SetLength для динамического массива (в отличие от строки, кстати), ты указываешь не номер последнего разрешенного элемента, а число элементов, которое на 1 больше этого номера. Притом, что минимальный разрешенный элемент имеет индекс 0, а не 1.
2) Динамические массивы - вообще дело тонкое, иногда можно сильно проиграть в скорости из-за скрытого перевыделения и копирования блоков памяти. Посмотри класс TList - он эффективнее, хотя и сложнее в использовании. А для самообразования можешь еще поиграть в связные списки.
Igorek (2004-07-01 16:04:00) [7]
> Pavelkq (01.07.04 15:57) [36]
Обычно размер массива известен сразу если ты его создаешь и заполняешь в одной процедуре (напр. [33].
А если ты время от времени увеличиваешь массив, то делай так:
SetLength(Mas, Length(Mas) + 1);
Mas[High(Mas)] := ...;
Amoeba (2004-07-01 15:59:00) [8]
> Pavelkq (01.07.04 15:57) [36]
О, Господи! Ему гоаорят "брито", а он все твердит, что "сторижено".
Pavelkq (2004-07-01 15:57:00) [9][32]Игорек, это пойдет, если заранее известно количество элементов. А в моем случае они обнаруживаются в этом же цикле. Хотя, можно дважды пройтись по всему массиву выяснив сначала его размеры, а потом заполнив...
Sandman25 (2004-07-01 15:53:00) [10]Нет. A[i-1].
Erik1 (2004-07-01 15:53:00) [11]Точнее в масиве SIndex элемента LemI нету. А то говорят всякое.
Pavelkq (2004-07-01 15:52:00) [12]А как же заполнять массив динамически расширяя его размеры?
Так можно:
For i=0 to 50 do
begin
SetLength(A,i);
A[i]:=i;
end;
Поправьте меня, если я ошибаюсь.
Igorek (2004-07-01 15:48:00) [13]
var
A: array of integer;
I: Integer;
begin
SetLength(A, 10);
for I := Low(A) to High(A) do
begin
A[I] = 0;
end;
Sandman25 (2004-07-01 15:38:00) [14][29] Pavelkq (01.07.04 15:33)
Объясняю.
При SetLength(A, 3) в массиве A появятся 3 элемента:
A[0], A[1] и A[2].
При указании
I := 0;
for J := 0 to do
begin
I := I + 1;
A[I] := ... // получаем ошибку, потому что обращения будут к элементам
// A[1], A[2] и A[3].
end;
begin...end (2004-07-01 15:38:00) [15]
> [29] Pavelkq (01.07.04 15:33)
Я говорю о том, что после
SetLength(Base.SIndex[LemI].Word,WordI)
элемента в массиве Word с индексом WordI у тебя нету. НЕТУ!
Pavelkq (2004-07-01 15:33:00) [16][27] О чем ты говоришь? Это же динамический массив и я его границы задаю непосредственно перед занисением туда данных?
SetLength(Base.SIndex[LemI].Word,WordI);
SetLength(Base.SIndex[LemI].Index,WordI);
Base.SIndex[LemI].Word[WordI]:=Indexes[i1].Word;
Base.SIndex[LemI].Index[WordI]:=Indexes[i1].Index;
Еще раз поясняю, что ошибка возникает при
SetLength(Base.SIndex[LemI].Index,WordI);
Люди, как другим способом можно оформить вышеуказанный массив данных?
WondeRu (2004-07-01 15:30:00) [17]2Pavelkq (01.07.04 14:19) [15]
>Может и для Пушкина, но я его на форуме не встречал. Может кто разъяснит, что это значит?
"Project Project1.exe faulted with message: 'access violation at 0x00401c79: write of address 0x00000001'. Process Stoped. Use Step or Run to continue."
Типичная ошибка Access violation (AV) - нарушение доступа (попытка выполнить неразрешенную операцию с памятью, например, попытка записи в буфер, предназначенный только для чтения, доступ к памяти сверх лимита пространства адресов текущей программы, доступ к запрещенной странице; доступ к странице, резидентно находящейся в памяти, но предназначенной для использования компонентом исполняющей системы (Executive) и т.п.)
Вот... удачи)
begin...end (2004-07-01 15:28:00) [18]Вот после этого:
> SetLength(Base.SIndex[LemI].Word,WordI);
верхняя граница у индексов массива Word стала WordI - 1.
А вот здесь:
> Base.SIndex[LemI].Word[WordI]:=Indexes[i1].Word;
ты обращаешься к элементу с индексом WordI. А его нету!
begin...end (2004-07-01 15:24:00) [19]
> [25] Pavelkq (01.07.04 15:21)
Ну ты где-то вышел за границы индексов массива.
Pavelkq (2004-07-01 15:21:00) [20][20] Почему оно должнопадать?
[22] Пример не рабочий из-за того, что используются внешние модули (dll, res, unit...)