Форум: "Начинающим";
Текущий архив: 2007.11.11;
Скачать: [xml.tar.bz2];
ВнизПроблемка с динамическим массивом Найти похожие ветки
← →
Elec3C © (2007-10-15 22:28) [0]Динамический массив
Есть некая запись:
TMyStruct = record
Field_0 : Byte;
Field_1 : Boolean;
Field_2 : Integer;
Field_3 : String;
Field_A : array[0..2] of Integer;
end;
...
MyStruct : array of TMyStruct;
...
Как создать две процедурки, которые бы добавляли/удаляли элементы в данном динамическом массиве.
P.S. Нашёл две процедурки, но они не совсем подходят к данному массиву.
procedure DelIndex(var A : TDynMyArray; Index : integer);
var Last : integer;
begin
Last:= High( A );
if Index < Last then move( A[Index+1], A[ Index ],
(Last-Index) * sizeof( A[Index] ) );
setLength( A, Last );
end;
procedure AddIndex( var A: TDynMyArray; Index: integer; ANew: TMyArray );
var Len : integer;
begin
Len:= Length( A );
if Index > = Len then Index := Len+1;
setLength( A, Len+1);
move( A[Index], A[ Index+1 ],
(Len-Index) * sizeof( A[Index] ));
A[Index] := ANew;
end;
← →
Megaman KN © (2007-10-15 23:15) [1]почему же не подходят? %-)
замени типы в заголовках процедур и все.
TMyArray --> TMyStruc
TDynMyArray --> TDynMyStruc = array of TMyStruc
← →
MetalFan © (2007-10-15 23:43) [2]
> Field_3 : String;
в этом должен быть затык...
как минимум будет кушатся память, как максимум - av.
выход вижу такой: перед move при удалении "обнулить" строку ручками (или сделать finalize(A[Index]), при добавлении сначало "зачистить" память какойнить FillChar или ZeroMemory
← →
Elec3C © (2007-10-16 00:02) [3]Так это я пробовал, не выходит.
Знач я пишу так:
в AddIndex
ZeroMemory(@A[Index].Field_3, SizeOf(String));
остальное:
...
var M : array of TDynMyStruct;
...
...
var N : TMyStruct;
...
N.Field_0 := 0;
N.Filed_3 := "123";
AddIndex(M, 1, N); пробовал(AddIndex(M, 0, N) - тоже самое.
...
CpuView - показывает, что ошибка в move.
← →
Германн © (2007-10-16 00:26) [4]
> Elec3C © (16.10.07 00:02) [3]
А где выделение памяти под содержимое строки? Срочно читать в учебники про тип String.
← →
MetalFan © (2007-10-16 00:33) [5]
> ZeroMemory(@A[Index].Field_3, SizeOf(String));
ZeroMemory(@A[Index], SizeOf(TMyStruct));
← →
Германн © (2007-10-16 00:45) [6]
> MetalFan © (16.10.07 00:33) [5]
Всё равно способ с использованием процедуры Move, указанный в [0] идёт лесом. Пока автор не поймет что тип String нечто иное, чем тип Integer он не справится с проблемой.
← →
Elec3C © (2007-10-16 00:49) [7]Всё равно таже ситуация:\
← →
Германн © (2007-10-16 01:05) [8]
> Elec3C © (16.10.07 00:49) [7]
>
> Всё равно таже ситуация:\
>
Ну вот. Что я и говорил.
Сначала где-то создал запись ANew: TMyArray, потом передал ссылку на неё параметром в procedure AddIndex, скопировал содержимое этой записи процедурой Move, потом ANew уничтожил или заменил её содержимое. И всё прежнее содержимое Field_3 вытекло через задний проход :(
← →
Sapersky (2007-10-16 02:44) [9]http://delphimaster.net/view/2-1192105505/
http://sapersky.narod.ru/files/Arrays.rar
← →
MetalFan © (2007-10-16 10:49) [10]
> Германн © (16.10.07 00:45) [6]
ну да, при удалении перед move нужно хотябы finalize вызвать, или "обнулить" string вручную
← →
Elec3C © (2007-10-16 17:15) [11]
> Sapersky
А по легче можно как-нить обойтись(т.б. двумя процедурками) или делать
как у вас в примере?
← →
Sapersky (2007-10-16 18:09) [12]Так их там две и есть - Arr_AddItem/Arr_DelItem.
Arr_AddItem, кроме показанного в примере метода, можно использовать ещё так:
Var
Rec : TMyRecord;
Rec.Pos := ...
Arr_AddItem(Arr, TypeInfo(TMyRecArr), Cnt, @Rec);
Arr_AddItem(Arr, TypeInfo(TMyRecArr), Cnt, nil);
Arr[Cnt-1].Pos := ...
Если не нравится хранение длины в отдельной переменной:
http://www.rsdn.ru/article/Delphi/dynarrays.xml
← →
Elec3C © (2007-10-16 19:26) [13]
> Sapersky
Спасибо.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.11.11;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.059 c