Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 联合成员数据对齐_C_Unions - Fatal编程技术网

C 联合成员数据对齐

C 联合成员数据对齐,c,unions,C,Unions,我在联盟中的数据对齐方面遇到了一些问题,我似乎无法解决。使用与下面类似的联合,联合的基址上似乎有一些数据偏移 typedef union MyUnion { struct MyStruct { uint16_t val_1; uint8_t val_2; uint8_t val_3; }data; uint8_t data_array[4]; }MyUnion; 在某种程度上,我已经用数据填充了结构 my_un

我在联盟中的数据对齐方面遇到了一些问题,我似乎无法解决。使用与下面类似的联合,联合的基址上似乎有一些数据偏移

typedef union MyUnion
{
    struct MyStruct
    {
        uint16_t val_1;
        uint8_t  val_2;
        uint8_t  val_3;
    }data;
    uint8_t data_array[4];
}MyUnion;
在某种程度上,我已经用数据填充了结构

my_union.data.val_1 = 65535;
my_union.data.val_2 = 0;
my_union.data.val_3 = 0;
然后我尝试使用数组访问数据。我希望在数组的基址处看到的是val_1255的第一个字节。但是,当访问数组中的数据时,它似乎与结构的基偏移了1字节

printf("Bytes of struct: %#08x\n", my_union.data.val_1);
printf("Bytes of array:  %#08x\n", my_array.data_array[0]);
无论我在上面输入什么值,结果都与此类似

Bytes of struct:  0x00ffff
Bytes of array:   0x0000ff
我最初认为,成员可能以某种方式被偏移,并且引用了不同的内存地址,但当我打印它们的地址时,它们是相同的

此外,如果我打印以下值,它们是相等的

printf("Bytes of struct: %#08x\n", my_union.data);
printf("Bytes of array:  %#08x\n", *(my_array.data_array - 1) );
输出:

    Bytes of struct:  0x00ffff
    Bytes of array:   0x00ffff

我肯定我错过了一些简单的东西,但我现在还不明白。提前感谢您的帮助。

这绝对是错误的:

printf("Bytes of array:  %#08x\n", my_array.data_array);
您正在打印数组第一个元素的地址,而不是您感兴趣的内容

无论如何,打印指针应该使用
%p
格式,所以一个好的编译器应该给你一个警告

要打印数组的内容,必须打印其中的每个元素。
uint8\u t
(而不是
unint8\u t
!)的正确格式说明符是宏
PRIx8

试试这个

printf("Bytes of struct: %#08x\n", *(uint32_t*)&my_union.data);
printf("Bytes of array:  %#08x\n", *(uint32_t*)my_union.data_array);

在小型endian计算机(Intel Core i7、Mac OS X 10.9.1 Mavericks、GCC 4.8.2)上运行以下程序:

#include <inttypes.h>
#include <stdio.h>

typedef union MyUnion
{
    struct MyStruct
    {
        uint16_t val_1;
        uint8_t  val_2;
        uint8_t  val_3;
    } data;
    uint8_t data_array[4];  // NB: was unint8_t!!!
} MyUnion;

int main(void)
{
    MyUnion my_union;

    my_union.data.val_1 = 0xFEDC;
    my_union.data.val_2 = 0xBA;
    my_union.data.val_3 = 0x98;

    printf("val_1 = 0x%.4" PRIX16 "; val_2 = 0x%.2" PRIX8 "; val_3 = 0x%.2" PRIX8 "\n",
           my_union.data.val_1, my_union.data.val_2, my_union.data.val_3);

    char const *pad = "";
    for (size_t i = 0; i < sizeof(my_union.data_array); i++)
    {
        printf("%sarray[%zu] = 0x%.2" PRIX8, pad, i, my_union.data_array[i]);
        pad = "; ";
    }
    putchar('\n');

    return 0;
}
这正是我所期望的。在big-endian机器上,您会得到不同的输出(或多或少,除了Intel之外的任何东西)


您需要调整此代码(或非常类似的代码),以演示您发现的任何问题,并显示修改后的代码和实际输出,以及您对期望的内容和期望不同输出的原因的解释。

您应该会遇到错误。发布一个sscce,而不是代码片段。您实际使用的工会与下面的工会有多相似?你真的能重现你在问题中表现出来的工会的问题吗?您能否显示编译的完整但最少的代码及其生成的输出,并确定运行它的编译器和平台?您选择的值对于诊断问题不是很好;您应该考虑分配(例如)0xFEDC到<代码> Valy1 ,也许是0xBA到<>代码> Valu2和0x89> <代码> Valy3。请参见MCTRE/MCVE@JonathanLeffler,这是完全不同的,结构包含一些奇怪的数据类型,即位字段结构,但联合体中结构的第一个成员是无符号短字符。我使用的是MingWGCC4.6.2。该平台是Altera公司的RISC软处理器,名为NIOSII。对示例中的值表示抱歉。我使用了一些可以单独跟踪字节的方法,它显示了上面的行为。数组数据总是从结构数据偏移一个字节。OK;你肯定有一个更复杂的问题。因此,您需要生成在您的环境中再现您的问题的最小代码-请参阅我的答案以获得可能的概要-然后显示该代码、实际输出、预期输出,以及解释您认为实际输出错误和预期输出正确的原因。RISC处理器是大端还是小端?我注意到您的评论“我使用了[values],其中我可以单独跟踪字节”是不准确的;您无法区分这两个0xFF字节,也无法区分这两个0x00字节。@JonathanLeffler抱歉,我的意思是调试时我没有将0xFF用于字节。我实际上使用了我可以看到的字节值。我基本上做了与您在环境中的示例相同的事情。我将很快发布这个示例。字节顺序是小端。谢谢。这正是我期望看到的。我也遍历了数组,得到了相同的字节偏移量。我也看到了你的其他评论。我会在那里答复的。谢谢
val_1 = 0xFEDC; val_2 = 0xBA; val_3 = 0x98
array[0] = 0xDC; array[1] = 0xFE; array[2] = 0xBA; array[3] = 0x98