结构的大小有char,double,int和at

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)


Pra*_*rav 9

......它给了我24,我很困惑.额外的7个字节是多少?

这些是编译器插入的填充字节.数据结构填充是依赖于实现的.

来自维基百科,数据结构对齐:

数据对齐意味着将数据放入存储器偏移量等于字大小的某个倍数,这会因CPU处理内存的方式而提高系统性能.为了对齐数据,可能需要在最后一个数据结构的末尾和下一个数据结构的开始之间插入一些无意义的字节,即数据结构填充.

  • @Henk:Windows x86上的`double`有alignment = 8. (7认同)
  • 在Windows(Visual C++)上,您可以使用#pragma pack(1)关闭填充.执行此操作时,请务必使用#pragma pack(push/pop). (2认同)

Ste*_*hen 8

要稍微扩展一下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个字节的大小.

  • 是的,一般来说,整个结构必须与“最对齐”成员具有相同的对齐方式。想象一下,如果您有一个由这些结构体组成的数组,则每个结构体都需要正确对齐其“double”成员,这只有在该结构体被赋予与“double”成员相同的对齐方式时才可能实现。 (2认同)