从另一个线程删除对齐的内存

时间:2014-02-07 10:32:59

标签: c++ multithreading memory simd eigen

(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”属性,它都会崩溃。

1 个答案:

答案 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的默认删除操作符的东西,这意味着它甚至没有遇到我的重载删除操作符,这最终意味着我错过了一个“虚拟”。

我很遗憾甚至忘记将类继承添加到问题中。

有时,我可能会遇到问题几个小时甚至几天。但在我发布在线问题后,我可以立即找到答案。如果你们中的任何一个人之前有过类似的问题;也许我对自己施加了太大的压力。

仍然,谢谢你,互联网。