Results 1 to 11 of 11

Thread: SizeOf(rec)

  1. #1
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289

    SizeOf(rec)

    Hoi

    Ik loop tegen iets raars aan wat ik niet kan verklaren.
    Als je naar onderstaande code kijkt en het aantal bytes op gaat tellen zie je dat er een verschil is tussen records afzonderlijk en het record waar alles in zit.

    No big deal over de size maar ben benieuwd waar het verschil in bytes vandaan komt.
    Wat zie ik hier over het hoofd?

    Alvast bedankt,
    Herby

    PHP Code:
    Size of rec1 is  5 bytes
    Size of rec2 is  4 bytes
    Size of rec3 is 32 bytes
    Size of rec4 is  4 bytes
                   
    45 bytes

    Size of rec is 48 bytes 


    Code:
    program recordtest;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      WinAPI.Windows,
      System.SysUtils;
    
    type
      TRec1 = record
        s : string[4];                    // 5 bytes = 1 byte Nr of characters + 4 bytes
      end;
    
      TRec2 = record
        i : integer;                      // 4 bytes
      end;
    
      TRec3 = record
        arr : array [0..31] of byte;      // 32 bytes
      end;
    
      TRec4 = record
        dw : DWORD;                       // 4 bytes
      end;
    
      TRec  = record
        s : string[4];                    //  5 bytes = 1 byte Nr of characters + 4 bytes
        i : integer;                      //  4 bytes
        arr : array [0..31] of byte;      // 32 bytes
        dw : DWORD;                       //  4 bytes
      end;                                // 45 bytes ==> SizeOf(Rec) = 48 ???
    
    
    
    
    var
      rec   : TRec;
      rec1  : TRec1;
      rec2  : TRec2;
      rec3  : TRec3;
      rec4  : TRec4;
    
    begin
      WriteLn (Format('Size of rec1 is %d bytes',[SizeOf(rec1)]));
      WriteLn (Format('Size of rec2 is %d bytes',[SizeOf(rec2)]));
      WriteLn (Format('Size of rec3 is %d bytes',[SizeOf(rec3)]));
      WriteLn (Format('Size of rec4 is %d bytes',[SizeOf(rec4)]));
      WriteLn;
      WriteLn (Format('Size of rec is %d bytes',[SizeOf(rec)]));
    
      readln;
    end.

  2. #2
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Waarden in records worden op 16, 32 of 64 bit grenzen opgeslagen (afhankelijk van het type, de size is dus minimaal altijd een veelvoud van 2 bytes).
    Wil je alles "Op elkaar gepakt" hebben, dan moet je een "Packed Record" definieren:
    Delphi Code:
    1. type
    2.   TRec = packed record
    3.     s : string[4];  
    4.     i : integer;      
    5.     arr : array [0..31] of byte;
    6.     dw : DWORD;
    7.   end;
    TMemoryLeak.Create(Nil);

  3. #3
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    maar dat verschijnsel heb je dan toch in alle records?

  4. #4
    Dat heb je ook in alle records. Maar het gaat om ruimte tussen de velden in hetzelfde record. In alle voorbeelden die je hebt, is er dus maar 1 record met dergelijke ruimte'verspilling', namelijk de laatste TRec, waar na de shortstring van 5 bytes 3 bytes wordt vrijgehouden tot de volgende 4 byte boundary omdat het volgende type een (4 byte) integer is.
    Last edited by GolezTrol; 19-May-19 at 04:45.
    1+1=b

  5. #5
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Quote Originally Posted by VideoRipper View Post
    Waarden in records worden op 16, 32 of 64 bit grenzen opgeslagen (afhankelijk van het type, de size is dus minimaal altijd een veelvoud van 2 bytes).
    Dus een record met twee losse byte waardes is dan 4 bytes? Dacht het niet...

    Een veld word op een grens die een veelvoud van de size is. Met een minimum van 8 bits dus.

    Delphi Code:
    1. program Project42;
    2.  
    3. {$APPTYPE CONSOLE}
    4.  
    5. uses
    6.   System.SysUtils;
    7.  
    8.   type  tx=record a,b: byte; end;
    9.  
    10. begin
    11.   writeln(sizeof(tx));
    12.   readln;
    13. end.

    Print dus "2"

  6. #6
    Dat klopt inderdaad niet. Het is afhankelijk van het type. Standaard voor ordinal types is de grootte van het type. Een byte is 1 en zal dus ook per byte uitgelijnd worden, daarom is een record met twee bytes ook maar 2 bytes groot. Een record met een byte en een int wordt 8 bytes groot, omdat de int wordt uitgelijnd op byte 4.

    Zie Internal Data Formats, Record types.
    1+1=b

  7. #7
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Het principe heet overigens natural alignment. Arrays en records krijgen de alignment van hun grootste component. Sizes worden doorgaans omhoog afgerond op de volgende macht van twee. (*)

    Dit geeft ook direct de bovengrens aan, je kan geen alignment hebben groter dan het grootste fundamentele type dat de compiler heeft (80-bit extended voor Delphi/x86 denk ik, dus 16bytes). FPC heeft float128 op PowerPC64 geloof ik, en er zijn wat trucjes voor MMX en SSE, maar nog niet echt die-hard zoals gcc of VS.

    De x86_64 ABI schrijft verder 16-byte alignment van de stack voor, dus de compiler beheerst typisch 16-byte alignment ook wel, zelfs als 80-bit extended niet ondersteund wordt.

    (*) de gedachte hierachter is dat de load/store van een fundamenteel type dan nooit een page grens overschrijdt. Al zijn er uitzonderingen als je handmatig met pointers naar records in buffers aan de gang gaat. Architecturen met strenge alignment eisen vinden dat dan ook niet leuk.
    Last edited by marcov; 19-May-19 at 15:55.

  8. #8
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Bedankt voor de info, als hobbybob programmeur mis ik toch wat basis kennis merk ik zo mee en dan :-)

  9. #9
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Veel van dit soort dingen kom je alleen tegen als je met meerdere architecturen gaat werken. Tegenwoordig zijn veel architecturen echter minder eenkennig wat dit betreft.

  10. #10
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    En altijd uitkijken met die alignments als je "echt lowlevel" gaat werken

  11. #11
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    alignment, endianess, delay slots, verschillen in memory synchronizatie (meer memory barriers nodig), bit addressing etc.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •