C 给定结构中灵活数组成员的绝对地址,如何获取结构的绝对地址?
请看下面我使用的结构。我希望以一种便携的方式解决这个问题 我用于查找结构的绝对地址的代码是:C 给定结构中灵活数组成员的绝对地址,如何获取结构的绝对地址?,c,C,请看下面我使用的结构。我希望以一种便携的方式解决这个问题 我用于查找结构的绝对地址的代码是:(char*)data-sizeof(struct block)(其中数据是结构块中数据的地址)。它在此结构上不起作用 我做了一个测试程序,最后一次断言失败 如果我更改无符号int-free:1到无符号整数两次打印都将打印12,因此sizeof给出了预期的结果 提前谢谢 #include <stdio.h> #include <stdlib.h> #include <asse
(char*)data-sizeof(struct block)代码>(其中数据是结构块中数据的地址)。它在此结构上不起作用
我做了一个测试程序,最后一次断言失败
如果我更改无符号int-free:1代码>到无符号整数代码>两次打印都将打印12,因此sizeof给出了预期的结果
提前谢谢
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct block {
size_t size;
struct block* next;
unsigned int free:1;
char data[];
};
int main(void)
{
struct block* avail;
struct block* b;
avail = malloc(sizeof(struct block) + 10);
printf("%zu \n", sizeof(struct block)); // prints 12
printf("%zu\n", avail->data - (char*)&avail->size); //prints 9
b = (struct block*)((char*)avail->data - 9);
assert(b == avail);
b = (struct block*)((char*)avail->data - sizeof(struct block));
assert(b == avail);
return 0;
}
#包括
#包括
#包括
它给了我正确的绝对地址 sizeof(struct block)-sizeof(char*)
应提供struct block
的大小,不包括数据
字段。因此,如果您有一个指向数据的指针
,则应该到达结构的开头
b = (struct block*)((char*)avail->data - (sizeof(struct block) - sizeof(char*));
assert(b == avail);
不过,我还没有对它进行测试。关于布局(和大小)的唯一保证
成员的地址(即包含位字段的单元)按其列表顺序递增,成员的类型适当对齐,并且在结构的开头没有填充,因此适当转换的指向结构的指针将生成指向其第一个成员的指针。编译器可以自由地在成员之间插入比对齐所需的更多的填充
但是,通常,插入的填充仅为对齐所需。此外,在大多数实现中,size\u t
和struct block*
的大小和对齐要求是相同的,在32位系统上为4字节,在64位系统上为8字节。然后,struct block
的大小是k=sizeof(size\u t)
的倍数,第一个k
字节由size
成员占用,下一个k
字节由next
指针占用
之后是宽度为1的无符号位字段。这样一个小位字段适合任何存储单元,因此实现可以自由选择任何大小的存储单元。自然选择是
- 一个字节,因为它是最小的单位
sizeof(int)
bytes,因为“普通”int对象具有执行环境架构建议的自然大小”
现在,如果选择包含位字段的单元的大小为一个字节,就像您(和我的实现)的情况一样,data
成员通常直接放置在该单元之后,偏移量为2*k+1
字节,因为char
的对齐为1。如果位字段的单位选择为int
大小,则数据的偏移量很可能为2*k+sizeof(int)
,在32位系统上可能等于sizeof(struct block)
,但在64位系统上则不相同
你可以很有可能使实现成为现实
offsetof(struct block, data) == sizeof(struct block)
通过在自由
和数据
之间插入适当宽度的未命名位字段(CHAR\u bit*sizeof(size\u t)-1
),但唯一可移植且保证工作的方法是
struct block *b_addr = (struct block*)((char*)(avail->data) - offsetof(struct block, data));
如链接问题的中所述。灵活数组成员的可能重复项不是指针,并且不计入结构的基本大小,因此这将产生错误的结果。
struct block *b_addr = (struct block*)((char*)(avail->data) - offsetof(struct block, data));