Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.06;
Скачать: CL | DM;

Вниз

Динамические массивы   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.048 c
4-1103567201
_snake_
2004-12-20 21:26
2005.02.06
Разница между RS422 и RS232


1-1105772482
Александр1
2005-01-15 10:01
2005.02.06
Работа с Word


14-1105969105
Aleksandr
2005-01-17 16:38
2005.02.06
Помнится был сайт...


6-1100972208
webmaster
2004-11-20 20:36
2005.02.06
Отпрака мыла через proxy сервер


1-1106642331
Толстый
2005-01-25 11:38
2005.02.06
Stringgrid