2

Possible Duplicate:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?

#include<stdio.h>

struct csie {
  char c;
  short s;
  int i;
  double e;
};  

struct ceis {
  char c;
  double e;
  int i;
  short s;
};

int main(void) {
  printf("csie = %d\n", sizeof(struct csie));
  printf("ceis = %d\n", sizeof(struct ceis));
  return 0;
}

Output is:

csie = 16

ceis = 24

Community
  • 1
  • 1
israkir
  • 2,111
  • 7
  • 30
  • 39

5 Answers5

5

The alignment of the structures are different.

The first structure:

struct csie {
  char c;  
  short s; // 3 bytes + 1 bytes of padding
  int i;   // 4 bytes
  double e; // 8 bytes
};  

struct ceis {
  char c; //1 byte + 7 bytes of padding
  double e; // 8 bytes
  int i; // 4 bytes
  short s; // 2 byte + 2 bytes of padding
};

In the first structure the char and the short can be packed into the same alignment block, while in the second struct they can't.

GWW
  • 43,129
  • 11
  • 115
  • 108
3

This is very architecture dependent, and you don't specify what type of system you're on.

However, assuming

  • char: 1 byte size, no alignment
  • short: 2 byte size, aligned to 2 byte boundaries
  • int: 4 byte size, aligned to 4 byte boundaries
  • double: 8 byte size, aligned to 8 byte boundaries

this is easily explained.

+------+    +------+
| char |  0 | char |
+------+    +------+
|      |  1 |      |
+------+    |      |
|      |  2 |      |
| short|    |      |
|      |  3 |      |
+------+    |      |
|      |  4 |      |
|      |    |      |
|      |  5 |      |
|  int |    |      |
|      |  6 |      |
|      |    |      |
|      |  7 |      |
+------+    +------+
|      |  8 |      |
|      |    |      |
|      |  9 |      |
|      |    |      |
|      | 10 |      |
|      |    |      |
|      | 11 |      |
|double|    |double|
|      | 12 |      |
|      |    |      |
|      | 13 |      |
|      |    |      |
|      | 14 |      |
|      |    |      |
|      | 15 |      |
+------+    +------+
         16 |      |
            |      |
         17 |      |
            |  int |
         18 |      |
            |      |
         19 |      |
            +------+
         20 |      |
            | short|
         21 |      |
            +------+
         22 |      |
            |      |
         23 |      |
            +------+

There is empty space (called padding) in your structures, because certain data structures must fall on certain byte boundaries.

Note that the struct as a whole must be aligned to 8 byte boundaries to maintain the alignment of its members; that's why there's extra padding on the tail of the second version.

ephemient
  • 198,619
  • 38
  • 280
  • 391
0

It almost certainly has something to do with alignment. Different types must be aligned differently in memory, and since the elements of one struct are in a different order than than the other, they are aligned differently.

How these differences play out vary greatly between architecture, OS and compiler. See the Wikipedia article and your OS/compiler's manual for more specific info.

Rafe Kettler
  • 75,757
  • 21
  • 156
  • 151
0

Many machines required that data types be aligned to appropriate boundaries in memory. In your case, it is probably that the CPU require doubles to be aligned to 8 byte boundaries.

So the char, short and int in the first structure only need to be padded by 1 byte while in the second struct 7 bytes of padding are required just between the char and the double.

darklion
  • 1,025
  • 7
  • 11
0

You're using a 64-bit machine. Thus all allocation is in 64-bit (8-byte) blocks. The double is 8 bytes and has to be in its own block. The other fields can share blocks.

Apparently the compiler isn't sophisticated enough to save space in the second version of your struct:

  • It allocates the first block for the char, thus wasting most of the block.
  • It allocates the second block for the double.
  • It allocates the third block for the int and the short.
John Pick
  • 5,562
  • 31
  • 31