结构大小和内存布局取决于#pragma pack

亚历克斯·F

考虑以下在VC ++ 2010中编译的程序:

#pragma pack(push, 1)    // 1, 2, 4, 8
struct str_test
{
    unsigned int n;
    unsigned short s;
    unsigned char b[4];
};
#pragma pack(pop)

int main()
{
    str_test str;
    str.n = 0x01020304;
    str.s = 0xa1a2;
    str.b[0] = 0xf0;
    str.b[1] = 0xf1;
    str.b[2] = 0xf2;
    str.b[3] = 0xf3;

    unsigned char* p = (unsigned char*)&str;
    std::cout << sizeof(str_test) << std::endl;
    return 0;
}

我在return 0;网上设置断点,并在调试器中从address开始查看内存窗口p我得到以下结果(sizeof以及内存布局,取决于pack):

// 1 - 10    (pack, sizeof)
// 04 03 02 01 a2 a1 f0 f1 f2 f3

// 2 - 10
// 04 03 02 01 a2 a1 f0 f1 f2 f3

// 4 - 12
// 04 03 02 01 a2 a1 f0 f1 f2 f3

// 8 - 12
// 04 03 02 01 a2 a1 f0 f1 f2 f3

两个问题:

  1. 为什么sizeof(str_test)12个装8个装?

  2. 为什么内存布局相同且不依赖于包值?

concept3d

为什么pack 8的sizeof(str_test)是12?

MSDN文档

成员的对齐将在n的倍数或成员大小的倍数(以较小者为准)的边界上。

在您的情况下,最大成员是4个字节,小于8个,因此将使用4个字节进行对齐。

为什么内存布局相同且不依赖于包值?

不允许编译器对结构成员重新排序,但是可以填充成员。对于包装8,则执行以下操作;

#pragma pack(push, 8)    // largest element is 4bytes so it will be used instead of 8
struct str_test
{
    unsigned int n; // 4 bytes
    unsigned short s; // 2 bytes        
    unsigned char b[4]; // 4 bytes
    //2 bytes padding here;
};
#pragma pack(pop)

因此sizeof(str_test)将为12。

好吧,似乎编译器(MSVC2010)根据类型更改了填充位置,在这种情况下,编译器(MSVC2010)unsigned char b[4];在结构的末尾放置了两个字节的填充。在您的情况下,这2个字节cc cc恰好在字符数组之后。

#pragma pack(push, 8)    // largest element is 4bytes so it will be used instead of 8
struct str_test
{
    unsigned int n; // 4 bytes
    unsigned short s; // 2 bytes 
    //2 bytes padding here;       
    int;  // 4 bytes

};
#pragma pack(pop)

我所做的是将最后一个成员从更改char[4]int,可以分别在情况6和8中分别减去最后一个和第一个成员的地址来进行验证。

在最后一个成员的情况下的内存转储int如下

04 03 02 01 a2 a1 cc cc f0 f1 f2 f3

在最后一个成员的情况下的内存转储unsigned char[4]如下

04 03 02 01 a2 a1 f0 f1 f2 f3 cc cc

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Tkinter .pack 布局理解

来自分类Dev

过度使用Pragma Pack(1)

来自分类Dev

#pragma pack(16)和#pragma pack(8)的效果总是一样吗?

来自分类Dev

为什么#pragma pack也影响结构自身的对齐方式?

来自分类Dev

Perl pack()和整数溢出

来自分类Dev

#pragma pack()调用有什么作用?

来自分类Dev

#pragma pack与-fpack-struct for Intel C

来自分类Dev

在GCC上使用pragma pack(pop,1)

来自分类Dev

Structure size and memory layout depending on #pragma pack

来自分类Dev

#Pragma Pack编译时发出警告

来自分类Dev

GCC上的#pragma pack(push,n)/#pragma pack(pop)和__attribute __((__ packed __,aligned(n)))有什么区别?

来自分类Dev

Pack = 4和Pack = 1使该结构不等同于其C声明

来自分类Dev

pack()之后JFrame的大小为奇数

来自分类Dev

如何获取和应用Service Pack

来自分类Dev

git verify-pack和blob数量

来自分类Dev

git gc不会删除/ objects / pack / preserved /中的.old-pack和.old-idx文件

来自分类Dev

git-receive-pack / git-upload-pack和git-http-backend之间的区别

来自分类Dev

在Borland C ++上将#pragma pack与#define一起使用

来自分类Dev

如何在C ++中显示当前的#pragma pack设置?

来自分类Dev

D3 Circle Pack布局,水平排列

来自分类Dev

Git:git verify-pack返回的对象“大小”的含义

来自分类Dev

.pack()之后的JInternalFrame不占用内部组件的大小

来自分类Dev

Tkinter Pack方法的“填充”和“扩展”选项之间的区别

来自分类Dev

struct.unpack和struct.pack如何工作?

来自分类Dev

struct.unpack和struct.pack如何工作?

来自分类Dev

使用HTML Agility Pack和Xpath解析HTML

来自分类Dev

pack://和c:\ uri之间的BitmapImage加载差异

来自分类Dev

如何使用QT删除.pack和.idx文件

来自分类Dev

Azure Pack和Azure Stack有什么区别?

Related 相关文章

  1. 1

    Tkinter .pack 布局理解

  2. 2

    过度使用Pragma Pack(1)

  3. 3

    #pragma pack(16)和#pragma pack(8)的效果总是一样吗?

  4. 4

    为什么#pragma pack也影响结构自身的对齐方式?

  5. 5

    Perl pack()和整数溢出

  6. 6

    #pragma pack()调用有什么作用?

  7. 7

    #pragma pack与-fpack-struct for Intel C

  8. 8

    在GCC上使用pragma pack(pop,1)

  9. 9

    Structure size and memory layout depending on #pragma pack

  10. 10

    #Pragma Pack编译时发出警告

  11. 11

    GCC上的#pragma pack(push,n)/#pragma pack(pop)和__attribute __((__ packed __,aligned(n)))有什么区别?

  12. 12

    Pack = 4和Pack = 1使该结构不等同于其C声明

  13. 13

    pack()之后JFrame的大小为奇数

  14. 14

    如何获取和应用Service Pack

  15. 15

    git verify-pack和blob数量

  16. 16

    git gc不会删除/ objects / pack / preserved /中的.old-pack和.old-idx文件

  17. 17

    git-receive-pack / git-upload-pack和git-http-backend之间的区别

  18. 18

    在Borland C ++上将#pragma pack与#define一起使用

  19. 19

    如何在C ++中显示当前的#pragma pack设置?

  20. 20

    D3 Circle Pack布局,水平排列

  21. 21

    Git:git verify-pack返回的对象“大小”的含义

  22. 22

    .pack()之后的JInternalFrame不占用内部组件的大小

  23. 23

    Tkinter Pack方法的“填充”和“扩展”选项之间的区别

  24. 24

    struct.unpack和struct.pack如何工作?

  25. 25

    struct.unpack和struct.pack如何工作?

  26. 26

    使用HTML Agility Pack和Xpath解析HTML

  27. 27

    pack://和c:\ uri之间的BitmapImage加载差异

  28. 28

    如何使用QT删除.pack和.idx文件

  29. 29

    Azure Pack和Azure Stack有什么区别?

热门标签

归档