dat*_*ili 20 c++ structure-packing
当我只运行代码片段时
int *t;
std::cout << sizeof(char) << std::endl;
std::cout << sizeof(double) << std::endl;
std::cout << sizeof(int) << std::endl;
std::cout << sizeof(t) << std::endl;
Run Code Online (Sandbox Code Playgroud)
它给我一个这样的结果:
1
8
4
4
Run Code Online (Sandbox Code Playgroud)
总计:17.
但是,当我测试包含这些数据类型的sizeof结构时,它给了我24,我很困惑.额外的7个字节是多少?
这是代码
#include <iostream>
#include <stdio.h>
struct struct_type{
int i;
char ch;
int *p;
double d;
} s;
int main(){
int *t;
//std::cout << sizeof(char) <<std::endl;
//std::cout << sizeof(double) <<std::endl;
//std::cout << sizeof(int) <<std::endl;
//std::cout << sizeof(t) <<std::endl;
printf("s_type is %d byes long",sizeof(struct struct_type));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
:编辑
我已经像这样更新了我的代码
#include <iostream>
#include <stdio.h>
struct struct_type{
double d_attribute;
int i__attribute__(int(packed));
int * p__attribute_(int(packed));;
char ch;
} s;
int main(){
int *t;
//std::cout<<sizeof(char)<<std::endl;
//std::cout<<sizeof(double)<<std::endl;
//std::cout<<sizeof(int)<<std::endl;
//std::cout<<sizeof(t)<<std::endl;
printf("s_type is %d bytes long",sizeof(s));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在它显示我16个字节.它是好的,还是我丢失了一些重要的字节?
ken*_*ytm 52
某些成员之间存在一些未使用的字节,以保持对齐正确.例如,默认情况下,指针位于4字节边界以提高效率,即其地址必须是4的倍数.如果struct只包含char和指针
struct {
char a;
void* b;
};
Run Code Online (Sandbox Code Playgroud)
然后b不能使用加法器#1 - 它必须放在#4.
0 1 2 3 4 5 6 7
+---+- - - - - -+---------------+
| a | (unused) | b |
+---+- - - - - -+---------------+
Run Code Online (Sandbox Code Playgroud)
在您的情况下,由于对齐,额外的7个字节来自3个字节,由于对齐int*,因此来自4个字节double.
0 1 2 3 4 5 6 7 8 9 a b c d e f
+---------------+---+- - - - - -+---------------+- - - - - - - -+
| i |ch | | p | |
+---------------+---+- - - - - -+---------------+- - - - - - - -+
10 11 12 13 14 15 16 17
+-------------------------------+
| d |
+-------------------------------+
Run Code Online (Sandbox Code Playgroud)
......它给了我24,我很困惑.额外的7个字节是多少?
这些是编译器插入的填充字节.数据结构填充是依赖于实现的.
来自维基百科,数据结构对齐:
数据对齐意味着将数据放入存储器偏移量等于字大小的某个倍数,这会因CPU处理内存的方式而提高系统性能.为了对齐数据,可能需要在最后一个数据结构的末尾和下一个数据结构的开始之间插入一些无意义的字节,即数据结构填充.
要稍微扩展一下KennyDM的优秀答案(肯尼 - 如果你愿意的话,请把它偷来补充你的答案),这可能是你的内存结构在编译器对齐所有变量后的样子:
0 1 2 3 4 5 6 7
+-------------------+----+-----------+
| i | ch | (unused) |
+-------------------+----+-----------+
8 9 10 11 12 13 14 15
+-------------------+----------------+
| p | (unused) |
+-------------------+----------------+
16 17 18 19 20 21 22 23
+------------------------------------+
| d |
+------------------------------------+
Run Code Online (Sandbox Code Playgroud)
因此,由于"ch"和"p"之间的3字节间隙以及"p"和"d"之间的4字节间隙,您的结构将获得7字节填充,因此大小为24字节.由于您的环境double具有8字节对齐(即它必须驻留在它自己的8字节块中,如上所示),整个struct也将是8字节对齐,因此甚至可以重新排序变量不会改变24个字节的大小.