3

When I want to store dynamic array of data in a C structure, there are two ways to write it:

typedef struct {
   int row;
   int col;
   char* data;
} item1;

Or

typedef struct {
   int row;
   int col;
   char data[];
} item2;

Both of them will work. But they got some differences on my 64bit Mac OSX, with gcc Apple LLVM version 5.1 (clang-503.0.38):

      sizeof(item1) is 16
      sizeof(item2) is 8

Why is the difference? And, what else are different for the two implementations?

The full testing code is:

#include <stdio.h>

typedef struct {
  int row;
  int col;
  char* data;
} item1;


typedef struct {
  int row;
  int col;
  char data[];
} item2;


int main() {
  printf("%d %d\n", sizeof(item1), sizeof(item2));
  return 0;
}

The output is:

16 8
Green Su
  • 2,318
  • 2
  • 22
  • 16

2 Answers2

6

Size of pointer is machine specific (whether it is 32-bit or 64-bit). The result would be 12 and 8 bytes respectively on 32 bit machine. For 64-bit machine, answer would be 16 and 8 bytes.
See the explanation

typedef struct {
   int row;         // 4 bytes
   int col;         // 4 bytes
   char* data;      // 4/8 bytes on 32/64-bit machine
}item1 ;  

Total size = 12/16 bytes on 32/64 bit machine.

typedef struct {
   int row;         // 4 bytes
   int col;         // 4 bytes
   char data[];     // 0 bytes --> Flexible array 
}item2 ;  

Total size = 8 bytes.

Why size of flexible array is 0?

C11: 6.7.2.1 (p18)

[...] In particular, the size of the structure is as if the flexible array member were omitted [...]

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    4+4+4=12. Are you missing something? xD – James Hunt Jun 24 '14 at 08:20
  • @JamesHunt; Yes. Iwas missing :) – haccks Jun 24 '14 at 08:44
  • I think 16 bytes for 64 bit is a good rule of thumb, but worth noting that [this answer](http://stackoverflow.com/a/2505999/360211) says it's controllable with pragmas and compiler settings, so may not always be the case. – weston Jun 24 '14 at 08:53
1
typedef struct item2 {
   int row;
   int col;
   char data[];
}

in this struct item2 we have 2 ints, so the size will be 2*sizeof(int) in most of the systems, and also we have an array char data[] with undefined size so it counts as zero in this case, I think if there is padding in the struct then the amount of elements that the array will store will be related with the pading, but I am not sure.

total= 8 bytes.

typedef struct item1 {
   int row;    
   int col;
   char* data;
}

In this struct we have 2 ints that means 8 bytes ocupped by ints, and a pointer in a 64 bit system that means another 8 bytes.

total= 16 bytes.

There are a few things you need to know, there is no padding in this case an neither in item2. and the diferrence between char* data; and char data[]; is that the last one is an array that will be allocated in the stack, and the first one is a pointer allocated in the stack that will be commonly used with dynamic memory from the heap.

sir psycho sexy
  • 780
  • 7
  • 19