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

时间:2014-06-27 15:25:52

标签: c malloc offsetof

我创建了以下代码来理解offsetof()和container_of()宏。这里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;
}

1 个答案:

答案 0 :(得分:1)

看起来代码正在尝试检查/演示malloc实现的内部工作方式。您的container宏正在运行,问题是您的Header结构定义不正确:

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

这意味着malloc保持内存中分配的大小,后跟指向块的指针。这不准确 - 您假设不存在额外的间接级别。您的代码最终会将数据块的内容解释为void*。由于你还没有初始化那个记忆,你会发现那里发生了什么(根据你给出的值,看起来你可能会看到指向下一个空闲区块的指针 - 当你malloc(0)你&#39时;不允许写入数据块,因此实现可能会使用它 - 例如,请参阅glibc malloc implementation中的struct malloc_chunk

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

typedef struct
{
   size_t size;
   char block[0];
} Header;

您还需要更改printf以打印block的地址:

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

当然,请注意,不能保证每个malloc实现都会在块之前实际存储块大小,因此这可能并不总是有效。