Sizeof a struct in C
Asked Answered
B

4

5

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 !

Brokendown answered 18/12, 2014 at 20:37 Comment(4)
char is not 1 byte.. but it's 4 bytes. 4x4 = 16+8+4+8+4Delphinus
i expect long long to be aligned on 8 byte boundary. I expect pointer to be aligned on 4 byte boundary. Gets half way from 18 to 40Scandian
You gave your k 8 bytes, but you aligned it at 4 byte boundary. Why? Also, why is pt suddenly only 1 byte long??? It is a pointer.Aryanize
The accepted answer in the question you linked given an example, not a definitive answer. Other answers point out that it is implementation dependent. The question of which the one you linked is marked as a duplicate of has a superior accepted answer than makes this very clear. Your compile's documentation will describe how structure packing and alignment is performed, and how to influence it with extensions or careful ordering or members of different sizes.Doriedorin
S
7

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!

Screen answered 18/12, 2014 at 20:41 Comment(2)
ah yes - 8 byte pointers. Why trailing padding? Efficiency - so that next thing is aligned on next major boundary?Scandian
The trailing padding is allocated so that arrays of the structure keep all the elements of the structure properly aligned.Screen
A
2

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).

Auditory answered 18/12, 2014 at 20:45 Comment(0)
B
0

It is because of alignment, gcc has

#pragma pack(push,n)
// declare your struct here
#pragma pack(pop)

to change it. Read here, and also __attribute__((__packed__)).

If you declare the struct

struct packed
{
   char c1[3];
   long long k;
   char c2;
   char *pt;
   char c3;
} __attribute__((__packed__));

then compiling with gcc, sizeof(packed) = 18 since

    c1: 3
    k : 8
    c2: 1
    pt: 4 // it depends
    c3: 1

Apparently Visual C++ compiler supports #pragma pack(push,n) too.

Burgin answered 18/12, 2014 at 20:58 Comment(0)
A
0

what is a size of structure?

#include <stdio.h>
struct {
    char a;
    char b;
    char c;
}st;
int main()
{
    printf("%ld", sizeof(st));
    return 0;
}

it shows 3 in gdb compiler.

Almanza answered 29/6, 2022 at 7:23 Comment(1)
The original poster wants to know how to determine the size of a struct which is not as straightforward as it looks (see the more advanced example in the question).Chancre

© 2022 - 2024 — McMap. All rights reserved.