gpt4 book ai didi

将结构指针转换为另一个嵌入式结构

转载 作者:行者123 更新时间:2023-12-04 18:17:16 25 4
gpt4 key购买 nike

我正在实现一个不需要内存分配的堆栈,只要它嵌入一个特殊的结构就可以采用任何结构。类似于 GNU's List执行。

任何结构必须嵌入才能在堆栈中工作的结构是:

struct stack_elem {
struct stack_elem *next;
};

我想与堆栈一起使用的结构是:
struct node {
double number;
char character;
int isNumber;
struct stack_elem elem;
};

所以堆栈看起来像这样:
node:            node:
+---------+ +---------+
|number | |number |
+---------+ +---------+
|character| |character|
+---------+ +---------+
|isNumber | |isNumber |
+---------+ +---------+
|elem | |elem |
| *next |----->| *next |
+---------+ +---------+ etc....

我正在编写一个名为 stack_entry 的宏转换嵌入式 elem结构到它的容器 node结构。这是我到目前为止所尝试的。 stack_entry将按如下方式使用:
struct stack_elem *top = peek(&stack);
struct node *converted_node = stack_entry(top, struct node, elem);
stack_entry将采用指向 stack_elem 的指针,要转换为的节点的类型以及该节点中元素的成员字段的名称。我尝试了几种方法来做到这一点,但都没有奏效。我意识到 STACK_ELEM指向 next项目,所以我试着减去 elem 的偏移量来自 struct node那没有用。以下是我尝试过的一些也不起作用的事情:
#define stack_entry(STACK_ELEM, STRUCT, MEMBER)       \
((STRUCT *) &(STACK_ELEM) - offsetof (STRUCT, MEMBER))

#define stack_entry(STACK_ELEM, STRUCT, MEMBER) \
((STRUCT *) ((uint8_t *) &(STACK_ELEM)->next \
- offsetof (STRUCT, MEMBER)))

什么是正确的算术?为什么不减去 next 的偏移量,因此 elem 的偏移量,如果它是结构中的最后一个元素,则产生节点?

GNU 列表 list_entry宏定义为:
#define list_entry(LIST_ELEM, STRUCT, MEMBER)           \
((STRUCT *) ((uint8_t *) &(LIST_ELEM)->next \
- offsetof (STRUCT, MEMBER.next)))

这是如何运作的?为什么是 next当它应该抓取同一节点内的容器结构时,这里涉及到,而不是 next一?

最佳答案

GNU 的 list_entry通过从结构的开头减去 next 的偏移量来工作。 next 的地址中的字段 field 。它实际上并没有取消引用 next指针。在 Linux 源代码中有一个用于此的通用宏,称为 container_of 。 ,您可能会觉得有帮助。链接的文章信息量很大。

在您第二次尝试定义 stack_entry 时,您减去了错误的偏移量(将其与 GNU list_entry 宏进行比较)。

关于将结构指针转换为另一个嵌入式结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11419833/

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