我正在使用链表查看一些内存管理(pool
+ malloc
+ free
)实现,我发现在大多数节点中每个节点都是这样的:< / p>
typedef struct node{
int usedSize;
node* next;
char mem[100];
}
然后free(ptr)
必须是:
free(void* ptr){
node* item = (node*)((char*)ptr - sizeof(node*) - sizeof(int));
\\some code to put the "item" back to the pool
}
我的问题是:
为什么我们不应该将char mem[100];
放在结构的开头以避免&#34;指针操作&#34;?
结果是:
typedef struct node{
char mem[100]; // moved to the beginning
int usedSize;
node* next;
}
然后free(ptr)
更简单:
free(void* ptr){
node* item = (node*)((char*)ptr);
\\some code to put "item" back to the pool
}
感谢。
答案 0 :(得分:1)
指针操作并不是特别复杂。它相当于编译时常数的减量。如评论中所述,它实际上应该是:
node* item = (node*)((char*)ptr - offsetof(struct node, mem));
将该标题放在内存上方允许内存由灵活的数组成员表示。灵活的阵列成员只能占据结构的最后位置。评论中也提到了这一点。
typedef struct node {
int usedSize;
node* next;
char mem[];
} node;
如果内存的大小很大,跳过数组到达下一个指针可能会刷新数据缓存行以加载簿记数据。但是,从数组向后跳转可能会访问已加载到缓存中的数据。