gpt4 book ai didi

c - 在结构中填充

转载 作者:太空狗 更新时间:2023-10-29 17:10:34 28 4
gpt4 key购买 nike

我知道有 padding in struct ( example from this post )

 struct A   -->8 bytes
{
char c;
char d;
//2 padding here
int i;
};
struct B -->12 bytes
{
char c;
//3 padding here
int i;
char d;
//3 padding here
};

现在,我不明白下面的例子:

 typedef struct {  -->**shouldn't it be 12 bytes**
int a;
char *str;
} TestS;

TestS s;

int main(int argc, char *argv[]) {

printf("An int is %lu bytes\n", sizeof( int )); -->4
printf("A Char * is %lu bytes\n", sizeof( char *)); -->8
printf("A double is %lu bytes\n", sizeof( double )); -->8

printf("A struct is %lu bytes\n", sizeof s); -->why 16?

return 0;

}

首先我认为它可能对齐到 8*N 字节(因为我使用 ubuntu-64),所以我尝试了更多结构。

  typedef struct {
int i;
char *str;
} stru_12;


typedef struct {
int i;
char *str;
char c;
} stru_13;

typedef struct {
int i;
char str[7];
} stru_11;

typedef struct {
char *str;
double d;
} stru_16;

stru_12 test12;
stru_13 test13;
stru_11 test11;
stru_16 test16;

int main (int argc, char *argv[]) {
printf("A test12 is %lu bytes, address is %p\n", sizeof test12, &test12);
printf("A test13 is %lu bytes, address is %p\n", sizeof test13, &test13);
printf("A test11 is %lu bytes, address is %p\n", sizeof test11, &test11);
printf("A test16 is %lu bytes, address is %p\n", sizeof test16, &test16);
}

Result:

A test12 is 16 bytes, address is 0x601060

A test13 is 24 bytes, address is 0x601090

A test11 is 12 bytes, address is 0x601080

A test16 is 16 bytes, address is 0x601070

抱歉拖了这么久。

我的问题是:

  • 为什么test12(int + char*)是16字节,test13(int + char * + char)是24字节?(好像偏爱8*N,但是12字节是允许的)

  • 为什么struct的地址差异是16个寻址单元(更多的padding?)

供您使用:

cache_alignment : 64

address sizes : 36 bits physical, 48 bits virtual

Ubuntu 14.04.1 LTS x86_64

最佳答案

第二个问题是实现定义的(实际上,第一个问题也是如此,但我会告诉你为什么你会得到你得到的间距)。您的平台显然是 64 位的,因此您的数据指针也是(64 位的)。这样,我们就可以窥视结构。


stru_12

typedef struct 
{
int i;
char *str;
} stru_12;

这是对齐的,因此 str 始终落在 8 字节边界上,包括在连续序列(数组)中。为此,在 istr 之间引入了 4 个字节的填充。

0x0000 i    - length=4
0x0004 pad - length=4
0x0008 ptr - length=8
======================
Total 16

如果数组以 said-same 开始(它将),则这些数组将始终在 8 字节边界上具有 ptr。因为在 istr 之间添加填充也使结构大小达到 8 的倍数,所以除此之外不需要额外的填充。


stru_13

现在,考虑一下这也是如何实现的:

typedef struct 
{
int i;
char *str;
char c;
} stru_13;

相同的填充将应用于 istr 以再次将 str 放置在 8 字节边界上,但是添加c 使事情复杂化。为了实现指针始终驻留在 8 字节边界(包括这些结构的序列/数组)的目标,该结构需要尾部填充,但是多少呢?好吧,我希望很明显整体结构大小需要是 8 的倍数,以确保任何嵌入式指针(也是 8 的倍数)正确对齐。在本例中,添加了 7 个字节的尾部填充,使大小达到 24 个字节:

0x0000 i    - length=4
0x0004 pad - length=4
0x0008 ptr - length=8
0x0010 c - length=1
0x0011 pad - length=7
======================
Total 24

stru_13(双人组)

所以试试这个。您可能认为我们之前拥有的相同字段,但顺序不同,将导致:

typedef struct 
{
char *str;
int i;
char c;
} stru_13;

好吧,我们知道我们需要 8 字节边界上的 str 和 4 字节边界上的 i,坦率地说,我们根本不关心 c(总是伴娘):

0x0000 ptr  - length=8
0x0008 i - length=4
0x000c c - length=1
0x000d pad - length=3
======================
Total 16

通过您的测试程序运行它,您会看到它像我们上面那样运行。它减少到 16 个字节。我们所做的只是将顺序更改为仍然支持我们要求的空间更友好的布局,并且我们将默认表示减少了 8 个字节(使用先前布局的原始结构的 三分之一)。说这是摆脱所有这些的重要事情是轻描淡写的说法。

关于c - 在结构中填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25054281/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com