Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Динамический массив типа Record [D6, WinXP]


Страницы:   1 2 3

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...)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо