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

Вниз

Почему не получаю реальный размер переменной?   Найти похожие ветки 

 
Delphi7   (2004-06-20 14:14) [0]

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

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!


 
YurikGL ©   (2004-06-20 14:15) [1]

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


 
Romkin ©   (2004-06-20 14:27) [2]

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


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

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:46) [4]

По-отдельности, это значит, ты должен записать все поля 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 15:13) [5]

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 :-(


 
default ©   (2004-06-20 15:14) [6]

вообще можно получить размер любой структуры, для этого придётся(это очень просто) подменить функции выделения, освобож-ия и перераспределения памяти менеджера памяти 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 20:59) [7]

Thanks bolshoe, popitaus razobratsa!


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

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



Страницы: 1 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.037 c
14-1087236609
ИМХО
2004-06-14 22:10
2004.07.04
У кого Windows XP?


1-1087737033
*Boba
2004-06-20 17:10
2004.07.04
Edit


9-1078941377
SoulSilver
2004-03-10 20:56
2004.07.04
Подкиньте идею (в общем хотя бы) насчет 2D игры


1-1087475308
AngelSAI
2004-06-17 16:28
2004.07.04
ImageList


3-1086866596
Artem03
2004-06-10 15:23
2004.07.04
Аналог функций CONVERT или CAST в Informix 9