![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамические массивы [D6, Win2k]
vint45 © (2005-01-25 14:29:00)Привет! Подскажите, будет ли правильно работать конструкция состоящая из динамического массива, элементами которого являются записи record. Причем записи содержат в себе длинные строки:
TDescHotKey = record
FormComp: integer;
Param: string; // ansistring
ShortCut: word;
IsNew: boolean;
end;
THotKeys = array of TDescHotKey;
Так вот, при работе с массивом THotKeys у меня возникают ошибки, после нескольких операций присваивания и перераспределения его элементов.
vint45 (2005-01-26 10:15:00) [1]
> Separator © (25.01.05 17:13) [16]
> И не забывай очищать после себя память
это напутствие или я действительно неправильно освобождаю память? :)
Спасибо, за PChar, но вопрос про строки остался открытым: почему неверно освобождается память под них, может это как-то связано со счетчиком обращений к ним? Вначале ветки меня уверяли, что со строками работать можно, так да или нет?
Sapersky (2005-01-25 17:31:00) [2]Нельзя двигать длиные строки!
см. TStringList.Delete (Classes.pas)
Separator (2005-01-25 17:13:00) [3]И не забывай очищать после себя память
Separator (2005-01-25 17:11:00) [4]Используй 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;
Erik1 (2005-01-25 17:05:00) [5]Нельзя двигать длиные строки! Перейди на тип ShortString.
vint45 (2005-01-25 16:57:00) [6]а причем здесь сами строки, мы же в Move двигаем только указатели на них, соответственно SizeOf считает размер указателя.
Separator (2005-01-25 16:48:00) [7]попробуй вычислять память каждой записи как: SizeOf(TDescHotKey) + СуммаВсех .Param
vint45 (2005-01-25 16:43:00) [8]гмм.. я тоже предполагал, что дело связано с выбождением строки, поэтому до процедуры Move явно высвобождал используемую под нее память:
Dispose(arrHotKeys[inc1].Param);
Move(...
но это не помогло.
Separator (2005-01-25 16:39:00) [9]Ошибка в SizeOf(TDescHotKey), так как используеться тип String, то размер будет вычесляться не правильно
vint45 (2005-01-25 16:36:00) [10]Пробовал, при третьем нажатии кнопки, сразу на входе процедуры массив имеет неправильную структуру.
Poirot (2005-01-25 16:33:00) [11]Попробуй походить дебагером
vint45 (2005-01-25 16:29:00) [12]Да, всегда. Т.е. вначале он инициализируется до трех элементов, а потом при каждом нажатии кнопки, удаляется и добавляется по одному элементу. 0+1 - это я просто так (для наглядности) оставил, 0 - это индекс массива, в данном случае удаляется первый элемент, а добавляется в конец массива.
begin...end (2005-01-25 16:21:00) [13]> [5] vint45 (25.01.05 16:13)
> Move(prArrHotKeys [0+1],prArrHotKeys[0],...)
Всегда ли перед нажатием кнопки массив состоит более чем из одного элемента?
vint45 (2005-01-25 16:13:00) [14]Вот, сделал код покомпактней:
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.
vint45 (2005-01-25 14:44:00) [15]я попробую сделать код покомпактнее и выложить его с указанием того, где возникает ошибка.
Arm79 (2005-01-25 14:43:00) [16]будет работать правильно
KSergey (2005-01-25 14:39:00) [17]Вполне все работает, в том числе и с приведенной конструкцией
Явная ошибка в программе, только гда-то не в приведенном куске.
begin...end (2005-01-25 14:30:00) [18]> vint45 (25.01.05 14:29)
Ошибки - ? Код - ?