2

我正在尝试正确加载一个具有 1 个字符作为布尔值的结构。看起来它应该可以正常工作,但是当我 printf 布尔数据时它失败了,因为它读取的是 4 个字节而不是 1 个字节。

typedef struct
{
    char magic[8];
    u32 version;
    bool updatable;
    u64 filetime;
    u32 region;
    u32 numentries;
    u32 fs1;
    u32 fs2;
    u8 *zonedata;
} fastfile;

int main(int argc, char **args)
{
    if(!args[1])
        return -1;
    u64 file_size;
    get_file_size(args[1], &file_size);
    u8* file_data = new u8[file_size];
    read_file(args[1], file_data, file_size); //ignore this just reading data

    fastfile* ff = (fastfile *)(file_data + 0); //this is where I setup my struct according to file data
}

这是我的结构,这是我调试时发生的情况:

http://puu.sh/3e091/1ab766dfc6.png

十六进制视图:

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00E7C910  49 57 66 66 75 31 30 30 00 00 01 0D 01 01 CA CC  IWffu100......ÊÌ
00E7C920  3F 53 50 A3 40 00 00 00 02 00 00 00 00 00 03 5B  ?SP£@..........[
00E7C930  78 DA EC 5D 09 7C 13 C5 FE DF A6 94 9B 02 0A 72  xÚì].|.Åþߦ”›..r

如您所见,指向文件时间的指针位于 0xE7C920 而不是 0xE7C91D

有什么想法可以让它按照我想要的方式工作吗?还是因为指针长度为 4 个字节而不能那样工作?

4

1 回答 1

5

因为padding。现代 C 实现中的大多数类型都与一个地址对齐,该地址是其大小的倍数。所以在一个结构中,当你有一个 char 后跟一个 uint64_t 时,两者之间最多可以有 7 个填充字节。在您的情况下,u32 和 bool 占用 5 个字节,因此只需三个字节即可对 u64 进行 8 对齐。

要便携地检测是否有填充,您可以使用offsetof来自<stddef.h>.

于 2013-06-12T12:28:02.167 回答