在将其标记为重复之前,请先阅读问题。
所以这可能是一个潜在的非常愚蠢的问题,但它困扰着我。我从阅读以及许多其他问题中知道,由于编译器添加的填充,C 结构中的字段不能保证是连续的。例如,根据C标准:
13/在结构体对象中,非位域成员和位域所在的单元的地址按声明顺序递增。指向结构对象的指针经过适当转换后,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象内可能有未命名的填充,但不是在其开头。
我正在写一个类似于unix的程序readelf
and nm
只是为了好玩,它涉及到处理文件中特定偏移处的字节以读取某些值的大量工作。例如,目标文件的前 62 个字节包含“文件头”。文件头的字节 0x00-0x04 编码一个 int,而 0x20-0x28 编码一个指针等。但是,我注意到在 readelf.c 的原始实现中,程序员做了这样的事情:
首先,它们声明一个结构体(我们称之为 ELF_H),其中的字段与文件头中的内容相对应(即第一个字段是一个 int,就像文件头中的前 4 个字节一样,第二个字段是一个 char,因为字节 0x04 elf 标头中的 -0x05 编码字符等)。然后他们所做的就是将整个 elf 文件复制到内存中,并将指向该内存开头的指针键入 ELF_H 类型。就像是:
FILE *file = fopen('filename', rb);
void *start_of_file = malloc(/* size_of_file */);
fread(start_of_file, 1, /* size_of_file */,file); // copies entire file into memory
ELF_H hdr = *(ELF_H) start_of_file; // type case pointer to be of type struct and dereference
完成此操作后,只需使用结构体的成员变量访问标头的每个部分即可。因此,他们不是使用指针算术来获取字节 0x04 处的内容,而是只执行 hdr.member2 (在结构中,它是第二个成员,后面跟着第一个 int 成员)。
如果结构体中的字段不能保证连续,这意味着如何工作?
我能找到的最接近的答案是here但在该示例中,结构体的成员具有相同类型。在ELF_H中,它们是不同的类型。
先感谢您 :)