我有一个无符号的64位字和一个位填充结构,它们都在下面给出。结构在一个联合内部,它包含几个(11个准确)相似但略微结构。
uint64_t final_data_word;
#pragma pack(1)
typedef struct control_block_format_1_s
{
uint8_t block_type_field:8;
uint8_t control_word_0:7;
uint8_t control_word_1:7;
uint8_t control_word_2:7;
uint8_t control_word_3:7;
uint8_t control_word_4:7;
uint8_t control_word_5:7;
uint8_t control_word_6:7;
uint8_t control_word_7:7;
}control_block_format_1_t;
typedef union
{
control_block_format_1_t *cb_1;
control_block_format_2_t *cb_2;
control_block_format_3_t *cb_3;
control_block_format_4_t *cb_4;
control_block_format_5_t *cb_5;
control_block_format_6_t *cb_6;
control_block_format_7_t *cb_7;
control_block_format_8_t *cb_8;
control_block_format_9_t *cb_9;
control_block_format_10_t *cb_10;
control_block_format_11_t *cb_11;
}block_payload_union_t;
#pragma pack()
我想将64位字中的64位解释为结构中的字段。所以我正在进行以下操作
block_payload_union_t *block_pload =(block_payload_union_t*)malloc(sizeof(block_payload_union_t*));
block_pload->cb_1 = (control_block_format_1_t*)(&final_data_word);
但我没有得到我的结构中最后一个字段的预期值。任何人都可以看到我正在做的任何问题吗?任何建议或意见都表示赞赏。
@Jonathan
我在代码中添加了以下注释
printf(" sizeof(union)=%zu \ n",sizeof(block_payload_union_t));
printf(" sizeof(cb1)=%zu \ n",sizeof(control_block_format_1_t));
printf(" FDW = 0x%.16lx \ n",final_data_word);
// printf(" * bp-> llp = 0x%.16lx \ n",* block_pload-> llp);
printf(" bp-> cb1-> block_type_fld = 0x%。2X \ n",block_pload-> cb_1-> block_type_field);
printf(" bp-> cb1-> control_word_0 = 0x%。2X \ n",block_pload-> cb_1-> control_word_0);
printf(" bp-> cb1-> control_word_1 = 0x%。2X \ n",block_pload-> cb_1-> control_word_1);
printf(" bp-> cb1-> control_word_2 = 0x%。2X \ n",block_pload-> cb_1-> control_word_2);
printf(" bp-> cb1-> control_word_3 = 0x%。2X \ n",block_pload-> cb_1-> control_word_3);
printf(" bp-> cb1-> control_word_4 = 0x%。2X \ n",block_pload-> cb_1-> control_word_4);
printf(" bp-> cb1-> control_word_5 = 0x%。2X \ n",block_pload-> cb_1-> control_word_5);
printf(" bp-> cb1-> control_word_6 = 0x%。2X \ n",block_pload-> cb_1-> control_word_6);
printf(" bp-> cb1-> control_word_7 = 0x%。2X \ n",block_pload-> cb_1-> control_word_7);
没有#pragma pack()的输出如下:
最终数据字0x1e00000000000000
sizeof(union)= 8
sizeof(cb1)= 9
FDW = 0x1e00000000000000
bp-> cb1-> block_type_fld = 0x00
bp-> cb1-> control_word_0 = 0x00
bp-> cb1-> control_word_1 = 0x00
bp-> cb1-> control_word_2 = 0x00
bp-> cb1-> control_word_3 = 0x00
bp-> cb1-> control_word_4 = 0x00
bp-> cb1-> control_word_5 = 0x00
bp-> cb1-> control_word_6 = 0x1E
bp-> cb1-> control_word_7 = 0x78
#pragma pack()的输出如下:
最终数据字0x1e00000000000000
sizeof(union)= 8
sizeof(cb1)= 8
FDW = 0x1e00000000000000
bp-> cb1-> block_type_fld = 0x00
bp-> cb1-> control_word_0 = 0x00
bp-> cb1-> control_word_1 = 0x00
bp-> cb1-> control_word_2 = 0x00
bp-> cb1-> control_word_3 = 0x00
bp-> cb1-> control_word_4 = 0x00
bp-> cb1-> control_word_5 = 0x00
bp-> cb1-> control_word_6 = 0x00
bp-> cb1-> control_word_7 = 0x0F
这与Jonathan的机器上的输出相似。
答案 0 :(得分:3)
您应该在sizeof(block_payload_union_t)
的通话中使用sizeof(block_payload_union_t *)
代替malloc()
。但是,在64位计算机上,它可能会给你相同的大小(8),所以你可以逃脱它,因为它是错误的。
您的block_payload_union_t
包含指向字段布局的指针而不是保留实际值,这有点奇怪。
您尚未向我们展示final_data_word
的声明。您是否检查了工会的规模与预期的规模?
在运行Lion(10.7.2)的Mac上,我从以下程序获得此输出:
使用#pragma pack(1)
:
sizeof(union) = 8
sizeof(cb1) = 8
FDW = 0xFEDCBA9876543210
*bp->llp = 0xFEDCBA9876543210
bp->cb1->block_type_fld = 0x10
bp->cb1->control_word_0 = 0x32
bp->cb1->control_word_1 = 0x28
bp->cb1->control_word_2 = 0x59
bp->cb1->control_word_3 = 0x43
bp->cb1->control_word_4 = 0x29
bp->cb1->control_word_5 = 0x17
bp->cb1->control_word_6 = 0x37
bp->cb1->control_word_7 = 0x7F
没有#pragma pack(1)
:
sizeof(union) = 8
sizeof(cb1) = 9
FDW = 0xFEDCBA9876543210
*bp->llp = 0xFEDCBA9876543210
bp->cb1->block_type_fld = 0x10
bp->cb1->control_word_0 = 0x32
bp->cb1->control_word_1 = 0x54
bp->cb1->control_word_2 = 0x76
bp->cb1->control_word_3 = 0x18
bp->cb1->control_word_4 = 0x3A
bp->cb1->control_word_5 = 0x5C
bp->cb1->control_word_6 = 0x7E
bp->cb1->control_word_7 = 0x10
你得到了什么?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#pragma pack(1)
typedef struct control_block_format_1_s
{
uint8_t block_type_field:8;
uint8_t control_word_0:7;
uint8_t control_word_1:7;
uint8_t control_word_2:7;
uint8_t control_word_3:7;
uint8_t control_word_4:7;
uint8_t control_word_5:7;
uint8_t control_word_6:7;
uint8_t control_word_7:7;
} control_block_format_1_t;
typedef union
{
long long *llp;
control_block_format_1_t *cb_1;
//control_block_format_2_t *cb_2;
//control_block_format_3_t *cb_3;
//control_block_format_4_t *cb_4;
//control_block_format_5_t *cb_5;
//control_block_format_6_t *cb_6;
//control_block_format_7_t *cb_7;
//control_block_format_8_t *cb_8;
//control_block_format_9_t *cb_9;
//control_block_format_10_t *cb_10;
//control_block_format_11_t *cb_11;
} block_payload_union_t;
#pragma pack()
int main(void)
{
long long final_data_word = 0xFEDCBA9876543210;
block_payload_union_t *block_pload =(block_payload_union_t*)malloc(sizeof(block_payload_union_t));
block_pload->cb_1 = (control_block_format_1_t*)(&final_data_word);
printf("sizeof(union) = %zu\n", sizeof(block_payload_union_t));
printf("sizeof(cb1) = %zu\n", sizeof(control_block_format_1_t));
printf("FDW = 0x%.16llX\n", final_data_word);
printf("*bp->llp = 0x%.16llX\n", *block_pload->llp);
printf("bp->cb1->block_type_fld = 0x%.2X\n", block_pload->cb_1->block_type_field);
printf("bp->cb1->control_word_0 = 0x%.2X\n", block_pload->cb_1->control_word_0);
printf("bp->cb1->control_word_1 = 0x%.2X\n", block_pload->cb_1->control_word_1);
printf("bp->cb1->control_word_2 = 0x%.2X\n", block_pload->cb_1->control_word_2);
printf("bp->cb1->control_word_3 = 0x%.2X\n", block_pload->cb_1->control_word_3);
printf("bp->cb1->control_word_4 = 0x%.2X\n", block_pload->cb_1->control_word_4);
printf("bp->cb1->control_word_5 = 0x%.2X\n", block_pload->cb_1->control_word_5);
printf("bp->cb1->control_word_6 = 0x%.2X\n", block_pload->cb_1->control_word_6);
printf("bp->cb1->control_word_7 = 0x%.2X\n", block_pload->cb_1->control_word_7);
return(0);
}
答案 1 :(得分:2)
将指针作为你工会的成员有什么意义?你可以通过演员表获得相同的结果。
如果你想要的是通过11个不同的结构访问数据(而不是指针),那么在联合中你不想直接使用指针而是结构:
typedef union
{
control_block_format_1_t cb_1;
control_block_format_2_t cb_2;
control_block_format_3_t cb_3;
control_block_format_4_t cb_4;
control_block_format_5_t cb_5;
control_block_format_6_t cb_6;
control_block_format_7_t cb_7;
control_block_format_8_t cb_8;
control_block_format_9_t cb_9;
control_block_format_10_t cb_10;
control_block_format_11_t cb_11;
} block_payload_union_t;
现在block_payload_union_t
结构的大小只有64位,您可以使用11个版本中的任何一个来处理这些数据。
答案 2 :(得分:2)
#pragma pack(1)指令会导致该成员在1字节边界的结构中打包,但是 #pragma pack 指令会对齐所有位字段在1位边界的结构/联合中。这就是最后一个领域开始的原因。检查 control_block_format_1_s 的 sizeof ,无论是8还是9。