Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Размер структуры (Record) ...


Автор: Robus 25.6.2009, 08:42
Здравствуйте.

Возник вопрос. Я хочу создать структуру(Record) фиксированного размера. Мне нужно получить структуру размером 512 байт, а полей в ней 64. Размеры полей по ходу написания программы меняются. Соответственно приходится сделать поле FREE из массива байт размером 512-(размер предыдущих описанных полей).
Например:
Код

TYPE TA=RECORD
       A:DWORD;
       B:BYTE;
       FREE:ARRAY[0..512-5-1] OF BYTE;
     END;


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

В идеале хотелось бы что-то вроде такого:
Код

TYPE TA=RECORD (SIZE:512)
       A:DWORD;
       B:BYTE;
     END;


Или на худой конец что-то вроде такого:
Код

TYPE TA=RECORD
       A:DWORD;
       B:BYTE;
       FREE:ARRAY[0..512-1-DWORD(TA)-DWORD(TA.FREE)] OF BYTE;
     END;


Как можно решить подобную проблему ?

Автор: 1000000dollars 25.6.2009, 09:34
Я вижу два варианта: 
1) работа с указателями и приведение типов (не люблю указатели, поэтому этот вариант не описываю)
2) использовать возможности языка для размещения разных переменных по одному адресу памяти (приведённый код делает именно так)


Код

PROGRAM Project2;
{$APPTYPE CONSOLE}

USES
 Windows,
 SysUtils;

TYPE
 T_512bytes = {отключает выравнивание}packed{/отключает выравнивание} array [0..511] of byte;
 T_A = {отключает выравнивание}packed{/отключает выравнивание} record
               A: Cardinal;
               B: Byte;
               C: boolean;
              end;

PROCEDURE Dump (data: T_512bytes);
           VAR
             i: integer;

           BEGIN
            WriteLn ('Dump: ');
            for i:=0 to 511 do
             Write (IntToHex (data[i],2));
            WriteLn;
           END;

VAR
 b : T_512bytes;
 r : T_A {расположить переменные по одному адресу}absolute{/расположить переменные по одному адресу} b;

BEGIN
 // забиваем память нулями, потому что менеджер памяти этого может и не сделать
 FillMemory (@b, 512, 0);

 // смотрим дамп памяти
 Dump (b);

 // запихиваем что-то в структуру
 r.A := $DEADC0DE;
 r.B := $FF;
 r.C := true;

 // смотрим дамп памяти
 Dump (b);

 // распечатываем размеры выделенного блока памяти и стурктуры 
 WriteLn ('Size of block = ', SizeOf (b));
 WriteLn ('Size of record = ', SizeOf (r));

 WriteLn ('Done.');
 ReadLn;
END.

Автор: CodeMonkey 25.6.2009, 10:48
Код
  TA = record
  case Byte of
    1: (
         A: DWord; 
         B: Byte
        );
    2: (_Dummy: array[0..511] of Byte);
  end;

Автор: Robus 25.6.2009, 12:19
Это оно !!! Низкий поклон для CodeMonkey !!! Работает как часы !!! Я правда не понимаю, для чего здесь case, и почему 1 а потом 2, а не 0 и 1. Но об этом я сейчас почитаю в сетях ... Теперь я хоть знаю что искать ...

Спасибо ещё раз !!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)