Форум: "Основная";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];
ВнизДинамические массивы Найти похожие ветки
← →
vint45 (2005-01-25 14:29) [0]Привет! Подскажите, будет ли правильно работать конструкция состоящая из динамического массива, элементами которого являются записи record. Причем записи содержат в себе длинные строки:
TDescHotKey = record
FormComp: integer;
Param: string; // ansistring
ShortCut: word;
IsNew: boolean;
end;
THotKeys = array of TDescHotKey;
Так вот, при работе с массивом THotKeys у меня возникают ошибки, после нескольких операций присваивания и перераспределения его элементов.
← →
begin...end © (2005-01-25 14:30) [1]> vint45 (25.01.05 14:29)
Ошибки - ? Код - ?
← →
KSergey © (2005-01-25 14:39) [2]Вполне все работает, в том числе и с приведенной конструкцией
Явная ошибка в программе, только гда-то не в приведенном куске.
← →
Arm79 © (2005-01-25 14:43) [3]будет работать правильно
← →
vint45 (2005-01-25 14:44) [4]я попробую сделать код покомпактнее и выложить его с указанием того, где возникает ошибка.
← →
vint45 (2005-01-25 16:13) [5]Вот, сделал код покомпактней:
type
THKActions = (hkaChoiceElList);
TDescHotKey = record
FormComp: integer;
Param: string;
Action: THKActions;
ShortCut: word;
IsNew: boolean;
end;
THotKeys = array of TDescHotKey;
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
arrHotKeys: THotKeys;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin // инициализация массива
SetLength(arrHotKeys,Length(arrHotKeys)+1);
arrHotKeys[High(arrHotKeys)].FormComp:=0;
arrHotKeys[High(arrHotKeys)].Param:="1";
arrHotKeys[High(arrHotKeys)].Action:=hkaChoiceElList;
arrHotKeys[High(arrHotKeys)].ShortCut:=118;
SetLength(arrHotKeys,Length(arrHotKeys)+1);
arrHotKeys[High(arrHotKeys)].FormComp:=0;
arrHotKeys[High(arrHotKeys)].Param:="5";
arrHotKeys[High(arrHotKeys)].Action:=hkaChoiceElList;
arrHotKeys[High(arrHotKeys)].ShortCut:=119;
SetLength(arrHotKeys,Length(arrHotKeys)+1);
arrHotKeys[High(arrHotKeys)].FormComp:=0;
arrHotKeys[High(arrHotKeys)].Param:="17";
arrHotKeys[High(arrHotKeys)].Action:=hkaChoiceElList;
arrHotKeys[High(arrHotKeys)].ShortCut:=121;
end;
procedure TForm1.Button1Click(Sender: TObject);
var prArrHotKeys: THotKeys;
begin
prArrHotKeys:=Copy(arrHotKeys);
// удаляем первый элемент с индексом 0
Move(prArrHotKeys[0+1],prArrHotKeys[0],(Length(prArrHotKeys)-1-0)*SizeOf(TDescHotKey));
SetLength(prArrHotKeys,Length(prArrHotKeys)-1);
// удаляем элемент
SetLength(prArrHotKeys,Length(prArrHotKeys)+1);
prArrHotKeys[High(prArrHotKeys)].FormComp:=0;
prArrHotKeys[High(prArrHotKeys)].Param:="0";
prArrHotKeys[High(prArrHotKeys)].Action:=hkaChoiceElList;
prArrHotKeys[High(prArrHotKeys)].ShortCut:=116;
Label1.Caption:=prArrHotKeys[0].Param;
arrHotKeys:=Copy(prArrHotKeys);
Label1.Caption:=arrHotKeys[0].Param;
end;
Уже при третьем нажатии кнопки Button1, на входе обработчика Button1Click массив arrHotKeys имеет неправильную структуру элементов, что в конечном счете приводит к Invalid Point Operation.
← →
begin...end © (2005-01-25 16:21) [6]> [5] vint45 (25.01.05 16:13)
> Move(prArrHotKeys[0+1],prArrHotKeys[0],...)
Всегда ли перед нажатием кнопки массив состоит более чем из одного элемента?
← →
vint45 (2005-01-25 16:29) [7]Да, всегда. Т.е. вначале он инициализируется до трех элементов, а потом при каждом нажатии кнопки, удаляется и добавляется по одному элементу. 0+1 - это я просто так (для наглядности) оставил, 0 - это индекс массива, в данном случае удаляется первый элемент, а добавляется в конец массива.
← →
Poirot © (2005-01-25 16:33) [8]Попробуй походить дебагером
← →
vint45 (2005-01-25 16:36) [9]Пробовал, при третьем нажатии кнопки, сразу на входе процедуры массив имеет неправильную структуру.
← →
Separator © (2005-01-25 16:39) [10]Ошибка в SizeOf(TDescHotKey), так как используеться тип String, то размер будет вычесляться не правильно
← →
vint45 (2005-01-25 16:43) [11]гмм.. я тоже предполагал, что дело связано с выбождением строки, поэтому до процедуры Move явно высвобождал используемую под нее память:
Dispose(arrHotKeys[inc1].Param);
Move(...
но это не помогло.
← →
Separator © (2005-01-25 16:48) [12]попробуй вычислять память каждой записи как: SizeOf(TDescHotKey) + СуммаВсех .Param
← →
vint45 (2005-01-25 16:57) [13]а причем здесь сами строки, мы же в Move двигаем только указатели на них, соответственно SizeOf считает размер указателя.
← →
Erik1 © (2005-01-25 17:05) [14]Нельзя двигать длиные строки! Перейди на тип ShortString.
← →
Separator © (2005-01-25 17:11) [15]Используй PChar и все будет ок:
type
THKActions = (hkaChoiceElList);
TDescHotKey = record
FormComp: integer;
Param: PChar;
Action: THKActions;
ShortCut: word;
IsNew: boolean;
end;
THotKeys = array of TDescHotKey;
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
arrHotKeys: THotKeys;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
SetLength(arrHotKeys,Length(arrHotKeys)+1);
arrHotKeys[High(arrHotKeys)].FormComp:=0;
arrHotKeys[High(arrHotKeys)].Param:= StrNew("1");
arrHotKeys[High(arrHotKeys)].Action:=hkaChoiceElList;
arrHotKeys[High(arrHotKeys)].ShortCut:=118;
SetLength(arrHotKeys,Length(arrHotKeys)+1);
arrHotKeys[High(arrHotKeys)].FormComp:=0;
arrHotKeys[High(arrHotKeys)].Param:= StrNew("5");
arrHotKeys[High(arrHotKeys)].Action:=hkaChoiceElList;
arrHotKeys[High(arrHotKeys)].ShortCut:=119;
SetLength(arrHotKeys,Length(arrHotKeys)+1);
arrHotKeys[High(arrHotKeys)].FormComp:=0;
arrHotKeys[High(arrHotKeys)].Param:= StrNew("17");
arrHotKeys[High(arrHotKeys)].Action:=hkaChoiceElList;
arrHotKeys[High(arrHotKeys)].ShortCut:=121;
end;
procedure TForm1.Button1Click(Sender: TObject);
var prArrHotKeys: THotKeys;
begin
prArrHotKeys:=Copy(arrHotKeys);
// óäàëÿåì ïåðâûé ýëåìåíò ñ èíäåêñîì 0
StrDispose(prArrHotKeys[0].Param);
Move(prArrHotKeys[0+1],prArrHotKeys[0],(Length(prArrHotKeys)-1-0)*SizeOf(TDescHotKey));
SetLength(prArrHotKeys,Length(prArrHotKeys)-1);
// óäàëÿåì ýëåìåíò
SetLength(prArrHotKeys,Length(prArrHotKeys)+1);
prArrHotKeys[High(prArrHotKeys)].FormComp:=0;
prArrHotKeys[High(prArrHotKeys)].Param:= StrNew("0");
prArrHotKeys[High(prArrHotKeys)].Action:=hkaChoiceElList;
prArrHotKeys[High(prArrHotKeys)].ShortCut:=116;
Label1.Caption:=prArrHotKeys[0].Param;
arrHotKeys:=Copy(prArrHotKeys);
SetLength(prArrHotKeys, 0);
Label1.Caption:=arrHotKeys[0].Param;
end;
← →
Separator © (2005-01-25 17:13) [16]И не забывай очищать после себя память
← →
Sapersky (2005-01-25 17:31) [17]Нельзя двигать длиные строки!
см. TStringList.Delete (Classes.pas)
← →
vint45 (2005-01-26 10:15) [18]
> Separator © (25.01.05 17:13) [16]
> И не забывай очищать после себя память
это напутствие или я действительно неправильно освобождаю память? :)
Спасибо, за PChar, но вопрос про строки остался открытым: почему неверно освобождается память под них, может это как-то связано со счетчиком обращений к ним? Вначале ветки меня уверяли, что со строками работать можно, так да или нет?
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.037 c