Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

struct representation in memory on 64 bit machine

Tags:

c

For my curiosity I have written a program which was to show each byte of my struct. Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>

#define MAX_INT 2147483647
#define MAX_LONG 9223372036854775807

typedef struct _serialize_test{
   char a;
   unsigned int b;
   char ab;
   unsigned long long int c;
}serialize_test_t;


int main(int argc, char**argv){
   serialize_test_t *t;
   t = malloc(sizeof(serialize_test_t));
   t->a = 'A';
   t->ab = 'N';
   t->b = MAX_INT;
   t->c = MAX_LONG;

   printf("%x %x %x %x %d %d\n", t->a, t->b, t->ab, t->c, sizeof(serialize_test_t), sizeof(unsigned long long int));

   char *ptr = (char *)t;

   int i;
   for (i=0; i < sizeof(serialize_test_t) - 1; i++){
      printf("%x = %x\n", ptr + i, *(ptr + i));
   }

   return 0;
}

and here is the output:

41 7fffffff 4e ffffffff 24 8
26b2010 = 41
26b2011 = 0
26b2012 = 0
26b2013 = 0
26b2014 = ffffffff
26b2015 = ffffffff
26b2016 = ffffffff
26b2017 = 7f
26b2018 = 4e
26b2019 = 0
26b201a = 0
26b201b = 0
26b201c = 0
26b201d = 0
26b201e = 0
26b201f = 0
26b2020 = ffffffff
26b2021 = ffffffff
26b2022 = ffffffff
26b2023 = ffffffff
26b2024 = ffffffff
26b2025 = ffffffff
26b2026 = ffffffff

And here is the question: if sizeof(long long int) is 8, then why sizeof(serialize_test_t) is 24 instead of 32 - I always thought that size of struct is rounded to largest type and multiplied by number of fields like here for example: 8(bytes)*4(fields) = 32(bytes) — by default, with no pragma pack directives?

Also when I cast that struct to char * I can see from the output that the offset between values in memory is not 8 bytes. Can you give me a clue? Or maybe this is just some compiler optimizations?

like image 852
JosiP Avatar asked May 15 '13 13:05

JosiP


People also ask

How a struct is stored in memory?

Struct members are stored in the order they are declared. (This is required by the C99 standard, as mentioned here earlier.) If necessary, padding is added between struct members, to ensure that the latter one uses the correct alignment. Each primitive type T requires an alignment of sizeof(T) bytes.

What will be the size of following struct for a 64 bit machine?

Personally, I think no matter the program is 32-bit or 64-bit , the size of structure should always be 16 bytes (since char is 1 byte long, and the alignment of double is 8 bytes).

How much memory does a struct take?

Structure Padding Processor doesn't read 1byte at a time from memory.It reads 1 word at a time. In 32 bit processor, it can access 4 bytes at a time which means word size is 4 bytes. Similarly in a 64 bit processor, it can access 8 bytes at a time which means word size is 8 bytes.

Are structs 8 byte aligned?

Assuming a 64-bit machine, any instance of struct foo1 will have 8-byte alignment.


1 Answers

On modern 32-bit machines like the SPARC or the Intel [34]86, or any Motorola chip from the 68020 up, each data iten must usually be ``self-aligned'', beginning on an address that is a multiple of its type size. Thus, 32-bit types must begin on a 32-bit boundary, 16-bit types on a 16-bit boundary, 8-bit types may begin anywhere, struct/array/union types have the alignment of their most restrictive member.

The total size of the structure will depend on the packing.In your case it's going as 8 byte so final structure will look like

typedef struct _serialize_test{

   char a;//size 1 byte

   padding for 3 Byte;

   unsigned int b;//size 4 Byte

   char ab;//size 1 Byte again

   padding of 7 byte;

   unsigned long long int c;//size 8 byte

}serialize_test_t;

in this manner first two and last two are aligned properly and total size reaches upto 24.

like image 130
Dayal rai Avatar answered Nov 01 '22 21:11

Dayal rai