当给定成员指针本身是指针类型时,我正在尝试访问结构容器。 container_of()在这种情况下不起作用,我必须手动计算偏移量,然后自己计算容器地址。我可以调用任何类似于container_of()的内核函数,但要注意这种情况吗?
例如下面的代码,
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
typedef struct A
{
int filler;
int *data;
}A;
int main(int argc, char *argv[])
{
A *a = malloc(sizeof(A));
a->data = malloc(sizeof(int));
printf("1st part: use container_of():\n");
printf("a: %p | a->data: %p\n", a, a->data);
int *member_ptr = a->data;
A *c = container_of(member_ptr, A, data);
printf("c: %p\n", c);
printf("2nd part: manually calculate offset: \n");
unsigned long offset = (unsigned long)(&(((A*)0)->data));
printf("a: %p | &(a->data): %p | offset: 0x%x | &(a->data) - offset: %p", a, &(a->data), offset, (unsigned long)(&(a->data)) - offset);
free(a->data);
free(a);
return 0;
}
使用container_of()时,第一部分指针c不等于a:
Use container_of():
a: 0x166d260 | a->data: 0x166d280
c: 0x166d278
第二部分效果很好
Manually calculate offset:
a: 0x166d260 | &(a->data): 0x166d268 | offset: 0x8 | &(a->data) - offset: 0x166d260
答案 0 :(得分:1)
您显然很错误地使用了它,这就是gcc(应该)向您发出incompatible-pointer-types
警告的原因。
应该是
A *c = container_of(&a->data, A, data);
不
A *c = container_of(a->data, A, data);
a->data
值和a
的地址之间绝对没有没有关系。
(建议:注意警告(或使用-Werror
进行编译,因此您别无选择)。