加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 07:07:41 所属栏目:百科 来源:网络整理
导读:(C)我在堆上分配了内存对齐的实例,然后在另一个线程中删除它们.代码如下所示: ALIGNED class Obj{public: ALIGNED_NEW_DELETE...};Thread 1:Obj *o = new Obj; // overloaded new for aligned memory allocationpostTask(o);Thread 2:o-runTask();delete o;
(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”属性的情况下崩溃.

解决方法

这很尴尬,问题出现在线程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的默认删除操作符的东西,这意味着它甚至没有遇到我的重载删除操作符,这最终意味着我错过了一个“虚拟”.

我甚至忘了将类继承添加到问题中,这是我的坏事.

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

还是,谢谢你,互联网.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读