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

Вниз

Как узнать тип и размер объекта на который указывает указатель?   Найти похожие ветки 

 
Константинов ©   (2004-09-05 13:02) [0]

Допустим есть TList.
var
P1 : ^byte;
P2 : ^string[25];
P3 : ^double;
P : Pointer;
begin
Добовляем элементы в список...
GetMem(P1,SizeOf(byte));
GetMem(P2,25);
GetMem(P3,SizeOf(bouble));
List.Add(P1);
List.Add(P2);
List.Add(P3);
...
Теперь необходимо считать данные из TList
или освободить память ( FreeMem )
for I := 0 to List.Items.Count - 1 do
begin
 P := List[I];
 Я получил адрес памяти, но не знаю какого типа данные и      сколько байт выделено процедурой GetMem...
end;

Есть ли функции, позволяющие получить хотя бы размер выделенной памяти?

Если нет, то подскажите способ хранения "разнокалиберных" данных
в одном списке.

Заранее спасибо!


 
jack128 ©   (2004-09-05 13:09) [1]

Константинов ©   (05.09.04 13:02)
Есть ли функции, позволяющие получить хотя бы размер выделенной памяти?

если покопаться в менеджере памяти, но наверно можно размер получить.. Но не нужно.


> Если нет, то подскажите способ хранения
>"разнокалиберных" данных
> в одном списке.

type
 TDataType: (dtInteger, dtByte, dtDouble, dtSingle);
 PDataRec = ^TDataRec;
 TDataRec = record
   DataType: TDataType;
   case TDataType of
      dtInteger: (i: Integer);
      dtByte: (b: Byte);
      dtDouble: (d: Double);
      dtSingle: (s: Single);
 end;


в поле DataType храни признак на какого типа данные у тя храняться и в зависимости от этого обращайся к вариантной части записи..


 
Defunct ©   (2004-09-05 13:11) [2]

Допустим есть TList.
var
P1 : ^byte;
P2 : ^string[25];
P3 : ^double;
P : Pointer;
begin
Добовляем элементы в список...
GetMem(P1,SizeOf(byte));
GetMem(P2,25); - Ошибка! должно быть SizeOf(P2^);
GetMem(P3,SizeOf(bouble));

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

нет

Если нет, то подскажите способ хранения "разнокалиберных" данных
в одном списке.


Например так:

PUntypedRecord = ^TUntypedRecord
TUntypedRecord = Record
 data : Pointer;
 size : Integer;
End;

Var UntypedData : PUntypedRecord;
   P1          : ^Double;
   P2          : ^String[25];

New(UntypedData);
New(P1);
UntypedData.Data := P1;
UntypedData.Size := SizeOf(P1^);
List.Add(UntypedData);

New(UntypedData);
New(P2);
UntypedData.Data := P2;
UntypedData.Size := SizeOf(P2^);
ListAdd(UntypedData);

и т.п.

Еще можно использовать Stream (там где это целесообразно, когда большие данные).


 
begin...end ©   (2004-09-05 13:12) [3]

ИМХО, такое возможно только для типизированных указателей (в твоём случае это P1 и P3, P2 - вообще непонятно, что такое), например:

SizeOf(P1^)

Только непонятно как-то Вы память выделяете: вроде для типизированных указателей обычно New/Dispose используют.


 
Семен Сорокин ©   (2004-09-05 13:18) [4]

Может автору Varinat подойдет?


 
Семен Сорокин ©   (2004-09-05 13:18) [5]

[4] Varinat = Variant :)


 
Defunct ©   (2004-09-05 13:43) [6]

> begin...end ©   (05.09.04 13:12) [3]
> что такое), например:

> SizeOf(P1^)

>>Defunct ©   (05.09.04 13:11) [2]

>> P1          : ^Double;


SizeOf(P1^) = SizeOf(Double) = 8


 
begin...end ©   (2004-09-05 14:26) [7]


> [6] Defunct ©   (05.09.04 13:43)

Э-э... Не понял...
На счёт SizeOf(P1^) = SizeOf(Double) = 8 я в курсе, и что?


 
Константинов ©   (2004-09-05 22:48) [8]

Спасибо! В принципе я и расчитывал, что придется определить тип, примерно как Defunct ©   (05.09.04 13:11) [2]
А насчет вариантных записей, думаю не помогут. Хранятся записи с полями из динамических массивов. Вобще-то я здорово запутался где и как уберечься от утечки памяти. Создал класс на базе TList но при попытке очистить лист вылетает AV вот сижу и думаю где его искать...


 
Erik1   (2004-09-06 13:33) [9]

Я думаю, что лучшее решение в [1]. Можно его усовершенствовать, например:
type
TDataType: (dtInteger, dtByte, dtDouble, dtSingle, dtCustom);
RPointer = record
  Size: Integer;
  Data: Pointer;
end;
PDataRec = ^TDataRec;
TDataRec = record
  DataType: TDataType;
  case TDataType of
     dtInteger: (i: Integer);
     dtByte: (b: Byte);
     dtDouble: (d: Double);
     dtSingle: (s: Single);
     dtCustom: (c: RPointer);
end;
Думаю идея понятна или закинуть поле Size прямо в TDataRec, тут надо смотреть по типу данных.



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

Форум: "Основная";
Текущий архив: 2004.09.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.036 c
3-1093068104
ZSerg
2004-08-21 10:01
2004.09.19
Слишком мало параметров. Требуется 1.


1-1094353730
Viper
2004-09-05 07:08
2004.09.19
TStringGrid


3-1093250981
Marat
2004-08-23 12:49
2004.09.19
Ошибка при входе в форум "Общие вопросы"


6-1089759908
Chlavik
2004-07-14 03:05
2004.09.19
как подключится под Proxy используя Indy TidSmtp?


14-1093714875
able
2004-08-28 21:41
2004.09.19
Охото узнать Ваше мнение.





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