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

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

Почему не получаю реальный размер переменной? [D6, WinXP]


Delphi7 ©   (2004-06-20 14:14:00) 

Почему не получаю реальный размер переменной?

type
 TLabelInfo = Record
               x,y: Integer;
               Width: Integer;
               Text: String;
             end;
 TQuestionInfo = Record
                  PictureX, PictureY: Integer;
                  LabelsCount: Byte;
                  LabelsArray: array of TLabelInfo;
                End;

var
 QuestionInfo: TQuestionInfo;
begin
 with QuestionInfo do
   begin
     PictureX:=10;
     PictureY:=10;
     LabelsCount:=1;
     SetLength(LabelsArray,1);
     with LabelsArray[0] do
       begin
         x:=10;
         y:=10;
         Width:=50;
         Text:='Data';
       end;
   end;
 ShowMessage(IntToStr(SizeOf(QuestionInfo)));
end;

Я думаю что я не правильно обращаюсь к переменной QuestionInfo.

П.С. Я хочу передать данную переменную функцие FileStream.WriteBuffer!


Кирюша   (2004-06-21 01:55:00) [1]

Удалено модератором


Delphi7   (2004-06-20 20:59:00) [2]

Thanks bolshoe, popitaus razobratsa!


default   (2004-06-20 15:14:00) [3]

вообще можно получить размер любой структуры, для этого придётся(это очень просто) подменить функции выделения, освобож-ия и перераспределения памяти менеджера памяти Delphi для поддержки массива элементов, каждый из которых содержит адрес выделенной памяти и её размер, следовательно выделение дин-ой памяти под элементы структуры должно происходить после подмены указанных функций. Потом примерно таким кодом можно достич желаемого
function GetRealRecSize(Rec: PChar; FormalRecSize: Cardinal): Cardinal;
var
 i, PointerMemSize: Cardinal;
begin
 Result := FormalRecSize;
 i := 1;
 while i <= FormalRecSize - 3 do begin
  PointerMemSize := GetPointerMemSize(Pointer(Rec^));
  if PointerMemSize = 0 then begin
  // под данных "адресом" не "числится" память
    Inc(Rec); // ищем поинтеры дальше
    Inc(i);
  end
  else begin
    Result := Result + PointerMemSize;
    Inc(Rec, 4);
    Inc(i, 4)
  end
 end;
end;

пример использования:
type
 TRecord = record
   B: Byte;
   P: Pointer;
   W: Word;
 end;
...
var
R: TRecord;
begin
...
BeginExchangeDelphiMemoryFunctions;
GetMem(R.P, 7);
ShowMessage(IntToStr(GetRealRecSize(PChar(@R), SizeOf(R))));
EndExchangeDelphiMemoryFunctions;
...
end.


Delphi7   (2004-06-20 15:13:00) [4]

Ops, samoe glavnoe zabili!
Pri programirovanii dannogo koda nam ne izvestna struktura TQuestionInfo, eto znachit chto TQuestioInfo mojet bit String, Integer, Record i t.d.

Tak chto v vashem sluchae, mi doljni imet informaciu o strukture peremennoi, a etogo mi ne znaem k sojaleniu :-(


Romkin   (2004-06-20 14:46:00) [5]

По-отдельности, это значит, ты должен записать все поля TQuestionInfo, кроме LAbelsArray (в файле указатель нафиг не нужен), впрочем, можно до кучи и его, а потом дописать собственно сам массив.
Со стрококй - тожесамо.
LabelsArray - это как раз и есть указатель на первый элемент массива в памяти. Запись в файл легко сделать, подав в BlockRead LabelsArray[0] - там var Buffer, указатель сам возьмется.
Я бы делал запись примерно так:
Arr := QuestionInfo.LabelsArray //Присваиваем указатель
QuestionInfo.LabelsArray := pointer(length(Arr)); //ставим в поле не адрес, а длину
Записываем QuestionInfo, потом следом весь массив.
Считываем:
Считываем QuestionInfo, получаем длину массива из поля LabelsArray: Len := integer(QuestionInfo.LabelsArray);
Устанавливаем массив: SetLength(QuestionInfo.LabelsArray, Len)
Считываем сам массив...
Все. Неаккуратно, правда, но пойдет.


Delphi7   (2004-06-20 14:35:00) [6]

Ie eto ponimau chto nado Text[1] peredovat, no mena interesuet est li vozmojnost obratitsa k adresu strukturi QuestionInfo, esli est to takje samo kak i v sluchae so String, kogda peredaiotsa adres vsei strukturi v pamiati (Text[1]), v moiom sluchae peredam adres dannoi strukturi v pamati.

P.S. Po otdelnosti ne podhodit, tak kak uzer budet peredavat vsego odnu peremennuiu, strukturu kotoroi mne ne izvestna. Chtobi bilo legko ponat, obiasnu chto, ia sozdau malenki komponent kotori sohranaet dannie v fail, ispolzuia FileStream i strukturu FAT. Posemu u mena vsego odna peremennaia, s neizvestnoi strukturoi!


Romkin   (2004-06-20 14:27:00) [7]

Да и не только string ;) array of TLabelInfo - тоже указатель, SetLength память выделяет. ТАк что и то, и то - в запись не входит. И писать надо отдельно


YurikGL   (2004-06-20 14:15:00) [8]

String - только указатель на строку Используй ShortString


Наверх

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