Reputation: 209
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:
i | c | j | d | total |
---|---|---|---|---|
0 | 2 | 6 | 14 | 16 |
w | c | total |
---|---|---|
0 | 16 | 32 |
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:
Upvotes: 0
Views: 124
Reputation: 51
You have a copy of the Global Edition of CS:APP3e.
As we state in the errata web page:
Note on the Global Edition: Unfortunately, the publisher arranged for the generation of a different set of practice and homework problems in the global edition. The person doing this didn't do a very good job, and so these problems and their solutions have many errors. We have not created an errata for this edition.
This is one of the many problems that got messed up.
Upvotes: 5
Reputation: 650
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;
}
Following Gerhardh's remark, code with offsetof.
#include <stdio.h>
#include <stddef.h>
struct P1
{
short i;
int c;
int *j;
short d;
long long end[];
};
int main(void)
{
struct P1 p1;
printf(" Offset Size Occupation\n");
printf("short i : %12zu %12zu %12zu\n", offsetof(struct P1, i), sizeof(p1.i), offsetof(struct P1, c));
printf("int c : %12zu %12zu %12zu\n", offsetof(struct P1, c), sizeof(p1.c), offsetof(struct P1, j)-offsetof(struct P1, c));
printf("int *j : %12zu %12zu %12zu\n", offsetof(struct P1, j), sizeof(p1.j), offsetof(struct P1, d)-offsetof(struct P1, j));
printf("short *d : %12zu %12zu %12zu\n", offsetof(struct P1, d), sizeof(p1.d), offsetof(struct P1, end)-offsetof(struct P1, d));
printf("end : %12zu \n", offsetof(struct P1, end));
return 0;
}
Upvotes: 0
Reputation: 213296
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...
Upvotes: 2