Home > Software design >  Space occupied by array of struct
Space occupied by array of struct

Time:09-29

A question I have on Problem 3.44 of the book Computer Systems: A Programmer's Perspective (3rd edition (6 October 2015)) on data alignment.

The problem:

For each of the following structure declarations, determine the offset of each feild, the total size of the structure, for 8-bit alignment:

struct P1 {short i; int c; int *j; short *d}
...
struct P4 {char w[16]; char *c[2]}
struct P5 {struct P4 a[2]; struct P1 t}

Answer given in the book:

  • struct P1:
i c j d total
0 2 6 14 16
  • struct P4:
w c total
0 16 32
  • struct P5:
a t total
0 24 40

What I don't get is why did struct P4 a[2] in P5 only takes 24 bytes?
Since P5.a is an array of P4 of size 2, shouldn't it occupy 2 * 32 (total size of P4) bytes?


To make sure I quote the book correctly, attaching the screenshots below: enter image description here enter image description here

CodePudding user response:

  • P1 is wrong. In case int* j occupies 8 bytes, then on any known real-world computer with 64 bit addressing, short* d will also occupy 8 bytes. For a total of 22 bytes, assuming no padding was inserted after i, which is unlikely. In case padding is inserted, the total size would be 24 bytes.

    On a real-world 64 bit system, the struct layout would be:

    short  i  size: 2   offset:  0
    int    c  size: 4   offset:  4
    int*   j  size: 8   offset:  8
    short* d  size: 8   offset: 16
    
  • What I don't get is why did struct P4 a[2] in P5 only takes 24 bytes?

    It doesn't. P4 = 32 bytes, no padding. 2 * 32 = 64 bytes. P5 will be 64 24 = 88 bytes.

If you are quoting the book correctly, then evidently it has not been proof-read from the programmer's perspective...

CodePudding user response:

A code to test: (Gives the occupation in structure, not the size).

#include <stdio.h>

struct P1
{
    short i;
    int c;
    int *j;
    short *d;
    long long end[];
};

struct P4
{
    char w[16];
    char *c[2];
    long long end[];
};

struct P5
{
    struct P4 a[2];
    struct P1 t;
    long long end[];
};

int main(void)
{
    struct P1 p1;
    printf("size of p1 : %zu\n", sizeof(p1));    
    printf("short i : %zu\n", (size_t)&p1.c - (size_t)&p1.i);
    printf("int c : %zu\n", (size_t)&p1.j - (size_t)&p1.c);
    printf("int *j : %zu\n", (size_t)&p1.d - (size_t)&p1.j);
    printf("short *d : %zu\n", (size_t)&p1.end - (size_t)&p1.d);

    struct P4 p4;
    printf("\nsize of p4 : %zu\n", sizeof(p4));
    printf("char w[16] : %zu\n", (size_t)&p4.c - (size_t)&p4.w);
    printf("char *c[2] : %zu\n", (size_t)&p4.end - (size_t)&p4.c);

    struct P5 p5;
    printf("\nsize of p5 : %zu\n", sizeof(p5));
    printf("struct P4 a[2] : %zu\n", (size_t)&p5.t - (size_t)&p5.a);
    printf("struct P1 t : %zu\n", (size_t)&p5.end - (size_t)&p5.t);

    return 0;
}
  • The flexible member array is just to mark the end.
  • Related