gpt4 book ai didi

c - 给定结构中灵活数组成员的绝对地址,如何获取结构的绝对地址?

转载 作者:太空宇宙 更新时间:2023-11-04 05:00:25 24 4
gpt4 key购买 nike

请参阅下面我使用的结构。我希望以一种可移植的方式解决这个问题。

我用来查找结构的绝对地址的代码是:(char*)data - sizeof(struct block);(其中数据是结构 block 中数据的地址) .它不适用于此结构。

我做了一个测试程序,如下所示,最后一个断言失败了。

如果我将 unsigned int free:1; 更改为 unsigned int free; 两个打印都将打印 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;
}

编辑:好像我在堆栈溢出时在这里找到了答案:

how to get struct's start address from its member's address

它给了我正确的绝对地址。

最佳答案

关于布局(和大小)的唯一保证

struct block {
size_t size;
struct block* next;
unsigned int free:1;
char data[];
};

是成员的地址(resp。包含位域的单元)按其列表顺序递增,成员根据其类型适当对齐,并且在 struct 的开头没有填充,所以指向结构的指针,适当转换后会产生指向其第一个成员的指针。编译器可以自由地在成员之间插入比对齐所需更多的填充。

然而,通常情况下,插入的填充只是对齐所需要的。此外,size_tstruct block* 的大小和对齐要求在大多数实现中都是相同的,在 32 位系统上都是 4 个字节,在 64 位系统上都是 8 个字节。则 struct block 的大小是 k = sizeof(size_t) 的倍数,前 k 字节由 size 成员占用,接下来的 k 字节由 next 指针占用。

之后是宽度为 1 的无符号位域。如此小的位域适合任何存储单元,因此实现可以自由选择任意大小的存储单元。自然的选择是

  • 一个字节,因为它是可能的最小单位,
  • sizeof(int) 字节,因为“‘普通’’int 对象具有执行环境架构建议的自然大小”。

现在,如果将包含位域的单元选择为一个字节的大小,就像您的实现(和我的)的情况一样,通常将 data 成员直接放置在该单元之后,偏移量为2*k+1 字节,因为 char 的对齐方式为 1。如果位域的单位选择为 int 大小,则 data 的偏移量很可能是 2*k + sizeof(int) ,在 32 位系统上可能等于 sizeof(struct block) ,但是不适用于 64 位系统。

您很有可能将实现带到 make

offsetof(struct block, data) == sizeof(struct block)

通过在 CHAR_BIT * sizeof(size_t) - 1free 之间插入适当宽度 (data) 的未命名位域,但唯一可移植且保证有效的方法是

struct block *b_addr = (struct block*)((char*)(avail->data) - offsetof(struct block, data));

如链接问题的 Greg Hewgill's answer 所述。

关于c - 给定结构中灵活数组成员的绝对地址,如何获取结构的绝对地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11291087/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com