簡體   English   中英

聯盟成員數據對齊

[英]Union member data alignment

我在聯合中遇到數據對齊問題,我似乎無法弄清楚。 使用類似於下面的聯合,聯盟的基地址似乎有一些數據偏移。

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_1的第一個字節,255。但是,當訪問數組中的數據時,它似乎從結構的基數偏移了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

我確定我錯過了一些簡單的東西,但此刻我無法弄明白。 感謝您提前提供的任何幫助。

在小端機器(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;
}

產生顯示的輸出:

val_1 = 0xFEDC; val_2 = 0xBA; val_3 = 0x98
array[0] = 0xDC; array[1] = 0xFE; array[2] = 0xBA; array[3] = 0x98

這是我所期待的。 你會在大端機器上獲得不同的輸出(除英特爾以外的任何東西,或多或少)。

您需要調整此代碼(或非常類似的代碼)來演示您認為自己遇到的任何問題,並顯示修改后的代碼和實際輸出以及您對期望內容的解釋以及您對不同輸出的期望。

這是明確錯誤的:

printf("Bytes of array:  %#08x\n", my_array.data_array);

您正在打印數組的第一個元素的地址,而不是內容,這是您感興趣的內容。

無論如何,打印指針應該使用%p格式,所以一個體面的編譯器應該給你一個警告。

要打印數組的內容,您必須打印它的每個元素。 uint8_t (不是unint8_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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM