C编程,使用container_of()宏获取值时出错

C编程,使用container_of()宏获取值时出错,c,malloc,offsetof,C,Malloc,Offsetof,我创建了以下代码来理解offsetof()和container_()宏。这里printf()显示两个不同的地址,而不是相同的地址。我做错了什么 #include <stdio.h> #include <stddef.h> typedef unsigned char Byte; #define container(ptr, type, member) \ ({

我创建了以下代码来理解offsetof()和container_()宏。这里printf()显示两个不同的地址,而不是相同的地址。我做错了什么

#include <stdio.h>
#include <stddef.h>

typedef unsigned char Byte;

#define container(ptr, type, member)               \
({                                                 \
   (type *)((Byte *)ptr - offsetof(type, member)); \
})

typedef struct
{
   size_t size;                  
   void *block;                  
}Header;

int main()
{
   void *ptr = malloc(3);
   Header *pHdr = container(ptr, Header, block);
   printf("%p %p\n", ptr, pHdr->block);
   return 0;
}
#包括
#包括
typedef无符号字符字节;
#定义容器(ptr、类型、成员)\
({                                                 \
(类型*)((字节*)ptr-偏移量(类型,成员))\
})
类型定义结构
{
大小;
空*块;
}收割台;
int main()
{
void*ptr=malloc(3);
标题*pHdr=容器(ptr、标题、块);
printf(“%p%p\n”,ptr,pHdr->block);
返回0;
}

代码似乎试图检查/演示malloc实现的内部工作。您的
容器
宏正在工作,问题是您的
标题
结构定义不正确:

typedef struct
{
   size_t size;
   void* block;
} Header;
这意味着
malloc
将分配的大小保留在内存中,后跟指向块的指针。这是不准确的-您假设不存在额外的间接级别。代码最终将数据块的内容解释为
void*
。由于您尚未初始化该内存,因此可以看到内存中发生了什么(从您给出的值来看,您可能看到了指向下一个空闲块的指针-当您
malloc(0)
时,您不允许写入数据块,因此实现可能会使用它-例如,请参阅中的
struct malloc\u chunk
).

更正确的结构定义(在clang-503.0.40/LLVM 5.1和VC 2012上都适用)是:

typedef struct
{
   size_t size;
   char block[0];
} Header;
您还需要更改
printf
以打印
块的地址

printf("%p %p\n", ptr, &pHdr->block);

注意,当然,不能保证每个<代码> MalcC++ 实现实际上会在块之前存储块大小,因此这可能并不总是有效的。无论你问什么,看起来都是错误的。你在哪里设置块指针?打印的实际值是什么?你的意思是printf(…&pHdr->block),编译器可能使用不同的

malloc
实现。它是开源的,您可以查看。