了解container_of

时间:2014-10-20 23:54:06

标签: c macros

我试图通过编写一个小程序来理解container_of宏,但我没有得到预期的结果。我写的程序是:

typedef struct node {
    int id1;
    int id2;
    struct node *next;
}node;

int main()
{
    node *n1, *n2;
    n1 = malloc(sizeof(node));
    n2 = malloc(sizeof(node));

    n1->id1 = 101;
    n1->id2 = 102;
    n1->next = n2;

    n2->id1 = 201;
    n2->id2 = 202;
    n2->next = NULL;

    node *obj = (node*)container_of(&n2, node, next);

    printf("%d\n", obj->id1);
    free(n1);
    free(n2);

    return 0;
 }

但是使用该代码,我得到一些随机数作为我的答案。任何我可能错的想法?​​

1 个答案:

答案 0 :(得分:5)

container_of是一个受欢迎的实用程序宏,但它不是该语言的标准功能。

container_of的第一个参数应该直接指向struct字段,即它应该直接指向更大对象的嵌套子对象。更大的对象是"容器"宏的名称是指。

您正在传递&n2 - 指向完全独立的局部变量的指针。这就是为什么它不起作用。 n2是一个自变量。它不是任何容器的一部分。

正确使用container_of的一个例子是

node **pnext = &n2->next;
int *pid = &n1->id1;

...
// Assume that now we want to restore `n2` knowing only `pnext`
node *obj = container_of(pnext, node, next);
assert(obj == n2);

...
// Assume that now we want to restore `n1` knowing only `pid`
obj = container_of(pid, node, id1);
assert(obj == n1);

即。从指向*n2对象的字段的指针,您将获得指向整个 *n2对象本身的指针。从指向*n1对象字段的指针,您可以获得指向整个 *n1对象本身的指针。

为什么你试图投射container_of的结果也不清楚。 container_of的传统实现已经返回正确转换的指针。