Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.03 c
8-1082481420
MIA
2004-04-20 21:17
2004.07.04
Звук (ошибка)


1-1087724542
M@verick
2004-06-20 13:42
2004.07.04
Добрый день всем. У меня при запуске отладчика выскакивает


1-1087879148
Cobalt
2004-06-22 08:39
2004.07.04
Как окно теряет фокус?


6-1083904771
-=DeMoH=-
2004-05-07 08:39
2004.07.04
Кто-нибудь знает, как работать с сокетами?


3-1086346203
Fishka
2004-06-04 14:50
2004.07.04
Excel "вылетает"





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский