-1

我创建了以下代码来理解 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;
}
4

1 回答 1

1

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

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

这意味着malloc将分配的大小保留在内存中,然后是指向块的指针。这是不准确的 - 您假设不存在额外的间接级别。您的代码最终将数据块的内容void*解释为. 由于您尚未初始化该内存,因此您会看到那里发生的任何事情(从您提供的值来看,您可能会看到指向下一个空闲块的指针 - 当您malloc(0)不允许写入数据时块,以便实现可以使用它 - 例如参见struct malloc_chunkglibc malloc 实现)。

更正确的结构定义(对我来说适用于 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实现都会在块之前立即存储块大小,因此这可能并不总是有效。

于 2014-06-27T16:53:08.903 回答