C位域的内存使用

4

我需要处理下列形式的一些数据:

typedef struct{
    unsigned n1 : 12;
    unsigned n2 : 12;
    unsigned n3 : 12;
    unsigned n4 :  1;
    unsigned n5 : 35;
} data;

我确保它们总共加起来是9个字节。但事实并非如此。将这个结构体的9个字节写入文件并读回来后,并不能恢复所有数据,sizeof(data)返回16。
问题出在哪里呢?


3
填充。无法保证编译器如何分配这些位和/或在结构体后插入多少填充。编译器喜欢将数据结构放置在偶数边界上。什么构成偶数边界受多种因素支配,其中包括处理器架构。 - Lou
4个回答

8
问题是编译器出于效率原因添加了一些填充。
这种行为可以被覆盖。
有关如何使用gcc进行此操作,请参见强制在GCC中对齐
有关如何使用Visual C++进行此操作,请参见:在Visual C++中强制对齐

1

1

你的结构体长度为9个字节。编译器会将其填充到16个字节,以提高缓存友好性。这可以通过使用特定于编译器的指令/关键字来关闭(一般情况下我不建议这样做)。请参见数据结构对齐


0

这在一个36位的计算机上会非常有效。你忘了告诉我们你是否拥有这样的计算机...

在一个更常见的32位机器上,使用9字节对齐将非常难以实现。如果你创建一个这些结构体的数组,你需要不同的代码来访问一个地址模0和一个地址模9的对象中的字段。

前三个字段的12位必须从不同的unsigned收集,并且根据地址的不同而有所不同。

除非你有具有位寻址功能(或者36位CPU)的硬件,否则其他答案中的打包指令在此处不太可能起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接