Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sizeof a struct in C

Well, after reading this Size of structure with a char, a double, an int and a t I still don't get the size of my struct which is :

struct s {
   char c1[3];
   long long k;
   char c2;
   char *pt;
   char c3;
}

And sizeof(struct s) returns me 40

But according to the post I mentioned, I thought that the memory should like this way:

  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
+-------------+- -+---------------------------+- - - - - - - -+
| c1          |   |k                          |               |
+-------------+- -+---------------------------+- - - - - - - -+
 10  11  12  13  14  15  16  17
+---+- -+- -+- - - - - -+----+
|c2 |   |pt |           | c3 |
+---+- -+- -+- - - - - -+----+

And I should get 18 instead of 40... Can someone explain to me what I am doing wrong ? Thank you very much !

like image 277
Raoul722 Avatar asked Dec 18 '14 20:12

Raoul722


2 Answers

Assuming an 8-byte pointer size and alignment requirement on long long and pointers, then:

  • 3 bytes for c1
  • 5 bytes padding
  • 8 bytes for k
  • 1 byte   for c2
  • 7 bytes padding
  • 8 bytes for pt
  • 1 byte   for c3
  • 7 bytes padding

That adds up to 40 bytes.

The trailing padding is allocated so that arrays of the structure keep all the elements of the structure properly aligned.

Note that the sizes, alignment requirements and therefore padding depend on the machine hardware, the compiler, and the platform's ABI (Application Binary Interface). The rules I used are common rules: an N-byte type (for N in {1, 2, 4, 8, 16 }) needs to be allocated on an N-byte boundary. Arrays (both within the structure and arrays of the structure) also need to be properly aligned. You can sometimes dink with the padding with #pragma directives; be cautious. It is usually better to lay out the structure with the most stringently aligned objects at the start and the less stringently aligned ones at the end.

If you used:

struct s2 {
   long long k;
   char *pt;
   char c1[3];
   char c2;
   char c3;
};

the size required would be just 24 bytes, with just 3 bytes of trailing padding. Order does matter!

like image 154
Jonathan Leffler Avatar answered Sep 19 '22 21:09

Jonathan Leffler


The size of the structure depends upon what compiler is used and what compiler options are enabled. The C language standard makes no promises about how memory is utilized when the compiler creates structures, and different architectures (for example 32-bit WinTel vs 64-bit WinTel) cause different layout decisions even when the same compiler is used.

Essentially, the size of a structure is equal to the sum of the size of the bytes needed by the field elements (which can generally be calculated) plus the sum of the padding bytes injected by the compiler (which is generally not known).

like image 21
Russell Kent Avatar answered Sep 20 '22 21:09

Russell Kent