簡體   English   中英

struct數組占用的空間

[英]Space occupied by array of struct

關於數據 alignment 的《計算機系統:程序員的觀點》 (第 3 版(2015 年 10 月 6 日))一書的問題 3.44,我有一個問題。

問題:

對於以下每個結構聲明,確定每個字段的偏移量,即結構的總大小,對於 8 位 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}

書中給出的答案:

  • 結構 P1:
一世 c j d 全部的
0 2個 6個 14 16
  • 結構 P4:
w c 全部的
0 16 32
  • 結構 P5:
一種 全部的
0 24 40

我不明白的是為什么P5struct P4 a[2]只占用 24 個字節?
由於P5.a是一個大小為 2 的P4數組,它不應該占用2 * 32 (total size of P4)字節嗎?


為了確保我正確地引用了這本書,附上下面的截圖: 在此處輸入圖像描述 在此處輸入圖像描述

您擁有 CS:APP3e 全球版的副本。

正如我們 state 在勘誤表 web 頁面中:

關於全球版的注意事項:不幸的是,出版商在全球版中安排了一組不同的練習和家庭作業問題。 做這件事的人做的不是很好,所以這些問題和解決方法有很多錯誤。 我們沒有為這個版本創建勘誤表。

這是被搞砸的眾多問題之一。

  • P1 是錯誤的。 如果int* j占用 8 個字節,那么在任何已知的具有 64 位尋址的真實計算機上, short* d也將占用 8 個字節。 對於總共 22 個字節,假設在i之后沒有插入填充,這是不可能的。 如果插入填充,則總大小為 24 字節。

    在真實世界的 64 位系統上,結構布局將是:

     short i size: 2 offset: 0 int c size: 4 offset: 4 int* j size: 8 offset: 8 short* d size: 8 offset: 16
  • 我不明白的是為什么 P5 中的 struct P4 a[2] 只占用 24 個字節?

    它沒有。 P4 = 32 字節,無填充。 2 * 32 = 64 字節。 P5將為 64 + 24 = 88 字節。

如果你正確地引用了這本書,那么顯然它沒有從程序員的角度進行校對......

要測試的代碼:(給出結構中的職業,而不是大小)。

#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;
}
  • 靈活的成員數組只是為了標記結束。

按照 Gerhardh 的評論,使用 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM