Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

array of Const и TVarRec [D6, XP]


Циркуль ©   (2008-10-06 12:56:00) 

Пытаюсь реализовать передачу в функцию Format() массива значений с неизвестным заранее количеством параметров.

Для примера слепил следющее:

var
 V: array of TVarRec;
 I: Integer;
 S: ShortString;
begin
 SetLength(V, 3);
 for I := Low(V) to High(V) do
 begin
   V[I].VType := vtString;
   S := ShortString(IntToStr(I));
   V[I].VString := @S;
 end;
 Caption := Format('%s %s %s' , V);
end;


Во первых не уверен, что верно присваиваю (раскопал такой код где-то в сети)

S := ShortString(IntToStr(I));
V[I].VString := @S;

Во вторых, не смотря на то, что код отрабатывает, не падая, в результате Caption получается "2 2 2", хотя по идее должен быть "0 1 2".

Короче, вопрос такой, как правильно инициализировать array of TVarRec строковыми значениями, что бы оно потом корректоно обрабатывалось функцией Format ?


MBo   (2008-10-07 05:12:00) [1]

может, еще будет полезно:
http://rvelthuis.de/articles/index.html


Leonid Troyanovsky   (2008-10-06 21:54:00) [2]


> Циркуль   (06.10.08 12:56)  
> Пытаюсь реализовать передачу в функцию Format() массива
> значений с неизвестным заранее количеством параметров.

http://groups.google.com/group/fido7.ru.delphi.chainik/msg/bb86dafbdd6277e9
see also
http://groups.google.com/group/fido7.ru.delphi/msg/150e16846702e545

--
Regards, LVT.


Игорь Шевченко   (2008-10-06 16:25:00) [3]


> компилятор создаст неявно три локальных переменных, в которых
> и будут храниться получаемые результаты функций и которые
> будут "жить" до выхода из области видимости (как "обычные"
> локальные переменные) ?


абсолютно верно


Циркуль   (2008-10-06 16:14:00) [4]

Т.е. в переводе с русского на более простой русский, то при

Arr[0].VAnsiString := PChar(stringfunc);
Arr[1].VAnsiString := PChar(stringfunc);
Arr[2].VAnsiString := PChar(stringfunc);

компилятор создаст неявно три локальных переменных, в которых и будут храниться получаемые результаты функций и которые будут "жить" до выхода из области видимости (как "обычные" локальные переменные) ?


Игорь Шевченко   (2008-10-06 15:59:00) [5]


> А нет ли опасности, если использовать приведение к PСhar
> не свойства, а
>
> Arr[x].VAnsiString := PChar(функция, возвращающая string);
>


Нет, опасности нет, потому что внутренняя реализация функции, возвращающей AnsiString, подразумевает, что буфер для строки-результата передается одним из параметров в функцию, то есть, он всегда находится на стороне вызывающего, следовательно, между вызовом функции и вызовом format он никуда не денется.


Циркуль   (2008-10-06 15:52:00) [6]

Спасибо, Игорь.

А нет ли опасности, если использовать приведение к PСhar не свойства, а

Arr[x].VAnsiString := PChar(функция, возвращающая string);

что Arr[x].VAnsiString к моменту вызова Format(.., Arr)  будет указывать на область памяти, забитую мусором (или что там произойдет Result'ом функции) ?


Игорь Шевченко   (2008-10-06 14:45:00) [7]

unit main;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Edit2: TEdit;
   Edit3: TEdit;
   Edit4: TEdit;
   procedure Button1Click(Sender: TObject);
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
 Arr: array of TVarRec;
begin
 SetLength(Arr, 3);
 Arr[0].VType := vtAnsiString;
 Arr[1].VType := vtAnsiString;
 Arr[2].VType := vtAnsiString;
 Arr[0].VAnsiString := PChar(Edit1.Text);
 Arr[1].VAnsiString := PChar(Edit2.Text);
 Arr[2].VAnsiString := PChar(Edit3.Text);
 Edit4.Text := Format('%s %s %s', Arr);
end;

end.


Циркуль   (2008-10-06 13:23:00) [8]

Спасибо :)


Сергей М.   (2008-10-06 13:20:00) [9]

Вру.
нужно, иначе утечка


Сергей М.   (2008-10-06 13:16:00) [10]

По идее не нужно


Циркуль   (2008-10-06 13:11:00) [11]

Спасибо, работает.

А после не нужно сделать

 for I := Low(V) to High(V) do
   Dispose(V[I].VString);

???


Сергей М.   (2008-10-06 13:06:00) [12]

var
V: array of TVarRec;
I: Integer;
p: PShortString;
begin
SetLength(V, 3);
for I := Low(V) to High(V) do
begin
  V[I].VType := vtString;
  New(V[I].VString);
  V[I].VString^ := IntToStr(I);
end;
Memo.Lines.Add(Format('%s %s %s' , V));
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо