我在C ++中遇到了new()
运算符的这个示例实现:
void *operator new(size_t size){
if(void *mem = malloc(size)){
cout << "allocated memory" << endl;
return mem;
}
else{
throw bad_alloc();
}
}
如何编辑此函数以便可以在特定的“字节边界”上分配内存(我指的是在性能圈中讨论的数据 alignment )?
(我假设这不是由编译器自动完成的 - 或者如果是,那么手动实现它有什么好处吗?)
答案 0 :(得分:3)
您需要找到一种方法来保留原始指针,否则您的free
会非常糟糕。
对齐是一个简单的例子(假设alignment
是2 n 值):
void *aligned = reinterpret_cast<void *>(
(reinterpret_cast<uintptr_t>(mem) + alignment-1) & ~(alignment-1));
但是,就像我说的那样,你需要将原始指针保存在某个地方。这可能意味着分配“有点extrra”(例如sizeof(void *)
)。
所以我们最终得到这样的东西:
assert(!(alignment & alignment-1)); // Don't like aligment not power of 2.
size_t extra = sizeof(void *);
void *mem = malloc(size + extra + alignment-1);
if (!mem)
throw bad_alloc();
void *aligned = reinterpret_cast<void *>(
(reinterpret_cast<uintptr_t>(mem) + extra + alignment-1) & ~(alignment-1));
void **ptr = reinterpret_cast<void **>(aligned);
ptr[-1] = mem;
return aligned;
然后在操作员删除中,您需要挖出原始指针:
operator delete(void *mem)
{
void **ptr = reinterpret_cast<void **>(mem); // This is the "aligned" pointer.
void *orig_mem = ptr[-1];
free(orig_mem);
}