Fscanf和结构对齐

fscanf and structure alignment

本文关键字:对齐 结构 Fscanf      更新时间:2023-10-16

我最近在调试代码时遇到了一个奇怪的bug。我有一个像这样的结构:

typedef struct
{
    uint8  val1;
    uint16 val2;
    uint8  val3;
    uint8  val4;
    uint16 val5;
    uint8  val6;
} foo;

,其中uint8uint16分别定义为unsigned charunsigned short int。我试图使用fscanf从tab分隔的文本文件扫描。代码是这样的:

foo f;
FILE* fptr = fopen("test.txt", "r");
if (fptr == NULL)
{
    printf("Error opening file");
    return;
}
if (6 == fscanf(fptr, "val2=%hut"
    "val1=%ut"
    "val3=%ut"
    "val4=%ut"
    "val5=%hut"
    "val6=%u", &f.val2, &f.val1, &f.val3, &f.val4, &f.val5, &f.val6))
    {
        //Some other code
    }
    else
    {
        printf("Error");
    }
    fclose(fptr);

在调试时,我发现无论我使用什么格式说明符或在文本文件中输入什么,存储在val2中的值都是0。我设法通过在foo的定义中切换val1val2来修复这个bug。我不明白的是为什么会出现这种情况。

我猜这和对齐有关,但如果有人能给我一个很好的解释,我真的很感激在第一种情况下到底发生了什么。

使用32位类型的格式说明符将指向8位变量(val1)的指针传递给scanf,将导致fscanf的写入超过该变量的末尾,从而越过结构体(val2和val3)的相邻成员(s)的顶部。

%u是unsigned int,所以scanf()认为它有一个4字节的地址来存储它的值。相反,它可能会将数据写入另外两个变量的内存地址。