![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблемка с динамическим массивом [D7]
Elec3C © (2007-10-15 22:28:00)Динамический массив
Есть некая запись:
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;
Elec3C (2007-10-16 19:26:00) [1]
> Sapersky
Спасибо.
Sapersky (2007-10-16 18:09:00) [2]Так их там две и есть - 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 17:15:00) [3]
> Sapersky
А по легче можно как-нить обойтись(т.б. двумя процедурками) или делать
как у вас в примере?
MetalFan (2007-10-16 10:49:00) [4]
> Германн © (16.10.07 00:45) [6]
ну да, при удалении перед move нужно хотябы finalize вызвать, или "обнулить" string вручную
Sapersky (2007-10-16 02:44:00) [5]http://www.delphimaster.ru/cgi-bin/forum.pl?id=1192105505&n=18
http://sapersky.narod.ru/files/Arrays.rar
Германн (2007-10-16 01:05:00) [6]
> Elec3C © (16.10.07 00:49) [7]
>
> Всё равно таже ситуация:\
>
Ну вот. Что я и говорил.
Сначала где-то создал запись ANew: TMyArray, потом передал ссылку на неё параметром в procedure AddIndex, скопировал содержимое этой записи процедурой Move, потом ANew уничтожил или заменил её содержимое. И всё прежнее содержимое Field_3 вытекло через задний проход :(
Elec3C (2007-10-16 00:49:00) [7]Всё равно таже ситуация:\
Германн (2007-10-16 00:45:00) [8]
> MetalFan © (16.10.07 00:33) [5]
Всё равно способ с использованием процедуры Move, указанный в [0] идёт лесом. Пока автор не поймет что тип String нечто иное, чем тип Integer он не справится с проблемой.
MetalFan (2007-10-16 00:33:00) [9]
> ZeroMemory(@A[Index].Field_3, SizeOf(String));
ZeroMemory(@A[Index], SizeOf(TMyStruct));
Германн (2007-10-16 00:26:00) [10]
> Elec3C © (16.10.07 00:02) [3]
А где выделение памяти под содержимое строки? Срочно читать в учебники про тип String.
Elec3C (2007-10-16 00:02:00) [11]Так это я пробовал, не выходит.
Знач я пишу так:
в 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.
MetalFan (2007-10-15 23:43:00) [12]
> Field_3 : String;
в этом должен быть затык...
как минимум будет кушатся память, как максимум - av.
выход вижу такой: перед move при удалении "обнулить" строку ручками (или сделать finalize(A[Index]), при добавлении сначало "зачистить" память какойнить FillChar или ZeroMemory
Megaman KN (2007-10-15 23:15:00) [13]почему же не подходят? %-)
замени типы в заголовках процедур и все.
TMyArray --> TMyStruc
TDynMyArray --> TDynMyStruc = array of TMyStruc