我已经读过这个关于结构填充C:http://bytes.com/topic/c/answers/543879-what-structure-padding 和写这个代码之后,文章应该怎么打印出来大小的结构垫像16字节和大小的结构pad2'应该是12.-因为我认为。我编写这个代码与海湾合作委员会,与不同级别的优化,甚至sizeof()操作者给了我他们两个16字节。为什么是这?

这个信息是必要的,对我来说,因为的PS3机,那里的字节的边界和剥削的全dma转让是重要的:

#include <stdio.h>
#include <stdlib.h>

struct pad
{
    char  c1;  // 1 byte
    short s1;  // 2 byte
    short s2;  // 2 byte
    char  c2;  // 1 byte
    long  l1;  // 4 byte
    char  c3;  // 1 byte
};

struct pad2
{
    long  l1;
    short s1;
    short s2;
    char  c1;
    char  c2;
    char  c3;
};

int main(void)
{
    struct pad P1;
    printf("%d\n", sizeof(P1));

    struct pad P2;
    printf("%d\n", sizeof(P2));

    return EXIT_SUCCESS;
}
有帮助吗?

解决方案

有两种技巧可以用来解决这个问题

  1. 使用指令#pragma pack(1)然后#pragma pack(pop) 例如:

    #pragma pack(1)
    
    struct tight{           
       short element_1;       
       int *element_2;
    };
    #pragma pack(pop) 
    
  2. 要在编译期间检查两个结构的大小是否相同,请使用此技巧

    char voidstr[(sizeof(struct1)==sizeof(struct2)) - 1]; //it will return error at compile time if this fail
    

其他提示

你的结构,每个都包括 long, 您的平台,显然需要应对一个四字节的边界。该结构必须至少作为对准作为其最盟成员,因此它已将4-byte结盟和结构的规模是一个多其准的情况下,进入阵列。

额外的填补所需要的 long 对准,并使最小的多的4个是16。

两片的建议:

  • 你可以计算出抵消的领域 l1 通过

     printf("Offset of field %s is %d\n", "l1", offsetof(struct pad, l1);
    

    得到的 offsetof 宏你会需要 #include <stddef.h> (谢谢你的咖啡馆!).

  • 如果你想要的数据,如人口密集的作为可能的使用 unsigned char[4] 而不是的 longunsigned char[2] 而不是的 short, 和做算术转换。


编辑::的 sizeof(struct pad2) 12.你的代码中有一个错误;结构 P2 声明的类型 struct pad.试试这个:

#define xx(T) printf("sizeof(" #T ") == %d\n", sizeof(T))
  xx(struct pad);
  xx(struct pad2);

P.S.我肯定应该停止试图回答这样的问题,午夜后。

在PS3上,不要猜。使用__attribute__((aligned (16)))或类似的。它不仅保证结构的开始将在适当的边界上对齐(如果是全局的或静态的),它还将结构填充到指定对齐的倍数。

您的代码未显示您的想法,因为P1和P2都被定义为struct pad的实例。从未使用过struct pad2。

如果我更改了P2的定义以使其成为struct pad2,那么gcc确实决定将其设置为12。

struct pad P1;
printf("%d\n", sizeof(P1));

struct pad P2;
printf("%d\n", sizeof(P2));

P1和P2具有相同的类型<!> quot; struct pad <!> quot;也许你想用<!> quot; struct pad2 <!> quot;对于P2。

所有CPU都希望内置数据类型(如int,float,char,double)以其自然边界存储在内存中,位于其长度的地址。因此,可以通过结构填充来更快地访问内存中的数据。 例如, 如果声明了int,它应该在内存中以4的地址出现,如

int的大小是4个字节。

同样,对于double,它以8的倍数驻留在内存中。

如果内存正确对齐,CPU可以更快地运行并高效工作。

对于以下示例,我们假设:

Sizeof(int)= 4字节

Sizeof(float)= 4字节

Sizeof(char)= 1个字节

详细了解 BoundsCheck

scroll top