(C ++)我在堆上分配了内存对齐的实例,然后在另一个线程中删除它们。代码如下所示:
ALIGNED class Obj
{
public: ALIGNED_NEW_DELETE
...
};
Thread 1:
Obj *o = new Obj; // overloaded new for aligned memory allocation
postTask(o);
Thread 2:
o->runTask();
delete o; // overloaded delete for aligned memory deletion
// "delete" statement crashes
线程2中的delete语句将在Visual Studio 2013中给出断言错误(_BLOCK_TYPE_IS_VALID)。 奇怪的是,如果我删除创建线程中的对象,一切运行正常。
为什么会这样?解决方案是什么?
修改
@ galop1n:实际上我目前使用的是Eigen的内置新/删除操作符EIGEN_MAKE_ALIGNED_OPERATOR_NEW。我也试过自己的操作员,都失败了。
对于Eigen的运营商,请自行查看其来源。
对于我的分配器:
void* operator new(size_t size){ return alignedMalloc(size, align); }
void operator delete(void* ptr) { alignedFree(ptr); }
void* operator new[](size_t size) { return alignedMalloc(size, align); }
void operator delete[](void* ptr) { alignedFree(ptr); }
void* alignedMalloc(size_t size, size_t align)
{
char* base = (char*)malloc(size + align + sizeof(int));
if (base == nullptr)
ASSERT(0, "memory allocation failed");
char* unaligned = base + sizeof(int);
char* aligned = unaligned + align - ((size_t)unaligned & (align - 1));
((int*)aligned)[-1] = (int)((size_t)aligned - (size_t)base);
return aligned;
}
void alignedFree(const void* ptr) {
int ofs = ((int*)ptr)[-1];
free((char*)ptr - ofs);
}
ALIGNED宏是__declspec(align(16))。无论有没有“ALIGNED”属性,它都会崩溃。
答案 0 :(得分:1)
这很尴尬,问题出现在线程2中,Obj *被转换为基类'指针Task *,并且完全愚蠢:~Task()不是虚拟的:
class Task
{
public:
~Task(); // <-- not virtual, therefore it crashes
...
}
ALIGNED class Obj : public Task
{ ... }
应该早点发现这个问题。因为,正如我对问题的描述一样,我自己说它会产生一个断言错误:_BLOCK_TYPE_IS_VALID,这是一个visual studio debug lib的默认删除操作符的东西,这意味着它甚至没有遇到我的重载删除操作符,这最终意味着我错过了一个“虚拟”。
我很遗憾甚至忘记将类继承添加到问题中。
有时,我可能会遇到问题几个小时甚至几天。但在我发布在线问题后,我可以立即找到答案。如果你们中的任何一个人之前有过类似的问题;也许我对自己施加了太大的压力。
仍然,谢谢你,互联网。