Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.49 MB
Время: 0.046 c
1-1106498375
Grigoryan
2005-01-23 19:39
2005.02.06
Показывать окно с сообщением сразу после появления главного окна


9-1099165943
Домовенок
2004-10-30 23:52
2005.02.06
[GLScene] FPSMovementManager


3-1105169378
Dell3r
2005-01-08 10:29
2005.02.06
Скролинг


3-1105198353
TechnoDreamer
2005-01-08 18:32
2005.02.06
Как программно изменить пароль на базе Access?


14-1106028347
syte_ser78
2005-01-18 09:05
2005.02.06
Получение закладок Word





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский