gpt4 book ai didi

C++ 获取条目的结构

转载 作者:太空狗 更新时间:2023-10-29 23:00:50 25 4
gpt4 key购买 nike

我在学习C++的数据结构和算法时遇到了如下代码。来自https://github.com/xtaci/algorithms/blob/master/include/double_linked_list.h第 194 到 206 行。

/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#ifndef _MSC_VER
#define list_entry(ptr, type, member) \
(reinterpret_cast<type *>((char *)(ptr)-(char *)(&(reinterpret_cast<type *>(1)->member))+1))
#else
#define list_entry(ptr, ptrtype, member) \
(reinterpret_cast<ptrtype>((char *)(ptr)-(char *)(&(reinterpret_cast<ptrtype>(1)->member))+1))
#endif

评论 block 说这个 Marco 的功能是获取这个条目的结构。令我困惑的是

reinterpret_cast<type *>(1)->member

将 1 转换为 (type *) 并访问其成员是什么意思?

* 提前感谢您的帮助。如果任何部分不清楚,我会尽快编辑。 *

* 更多信息 *:

代码中使用这个Marco来定义新的Marco

#define list_for_each_entry_safe(pos, n, head, member)          \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))

新 Marco 的用法示例来自 https://github.com/xtaci/algorithms/blob/master/include/graph_defs.h第 45 到 51 行作为析构函数的一部分。

        struct Adjacent {
struct Vertex v;
int32_t color; // color for searching
int32_t d; // discover time
int32_t f; // finish time
struct list_head v_head; // vertex list header
struct list_head a_node;
uint32_t num_neigh; // num of neighbours

Adjacent(uint32_t id):v(id) {
INIT_LIST_HEAD(&v_head);
num_neigh = 0;
}

~Adjacent() {
Vertex * v, *vn;
list_for_each_entry_safe(v, vn, &v_head, v_node){
list_del(&v->v_node);
delete v;
}
}
......

最佳答案

&(reinterpret_cast<type *>(1)->member)

这个语句如果像宏offsetof , 用于获取结构中成员的偏移地址。

棘手的reinterpret_cast<type *>(1)告诉编译器有一个 type *地址为0x1的指针, 然后 &(reinterpret_cast<type *>(1)->member)得到成员的偏移地址加上原来的0x1

我已经使用下面的代码来验证它。

struct list_head {
struct list_head *next, *prev;
};

struct Vertex {
int x;
int y;
list_head v_node;
};

int main()
{
Vertex *v = (Vertex *) malloc(sizeof(Vertex));
printf("%p", &(reinterpret_cast<Vertex *>(1)->v_node));
return 0;
}

它打印0x9 , 正是 2*sizeof(int) + 1

我个人认为使用 1而不是 0可以避免编译器将其视为无效的 NULL 指针。所以在宏中,1尾部又是加号。

list_entry可以这样使用

int main()
{
Vertex *v = (Vertex *) malloc(sizeof(Vertex));
Vertex *w = list_entry(&(v->v_node), Vertex, v_node);
printf("%p\n%p\n", v, w);
return 0;
}

当我们只有指向 list_head 的指针时我们可以使用 list_entry获取外部结构。在上面的代码中,vw指向同一区域。

关于C++ 获取条目的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32645319/

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