concurrent_queue导致内存损坏

时间:2011-12-24 12:07:32

标签: c++ visual-studio-2010 concurrency c++11

我的并发系统中存在内存损坏问题。

我有一个不是线程安全的内存分配器,我试图通过按需向多个线程提供多个实例来使其成为线程安全的。此代码显示我正在使用的系统。它有效地构建了一个实例队列。如果队列为空,则创建一个新实例,否则将从队列中取出一个实例。当线程完成实例时,它会将其推回到队列中以便以后再次使用。

Concurrency::concurrent_queue<std::shared_ptr<Memory::Arena>> result_memory_arenas;
//std::
struct ConcurrentMemoryArena {
    Context* ptr;
    std::shared_ptr<Memory::Arena> arena;
    Memory::Arena& operator*() { return *arena; }
    Memory::Arena* operator->() { return arena.get(); }
    ~ConcurrentMemoryArena() {
        if (arena)
            ptr->result_memory_arenas.push(arena);
    }
    ConcurrentMemoryArena(Context* owner)
        : ptr(owner) {}
    ConcurrentMemoryArena(ConcurrentMemoryArena&& other) {
        arena = std::move(other.arena);
        other.arena = nullptr;
        ptr = other.ptr;
    }
};
ConcurrentMemoryArena ConcurrentGetResultArena() {
    ConcurrentMemoryArena ret(this);
    /*if (!result_memory_arenas.empty()) {
        ret.arena = result_memory_arenas.front();
        result_memory_arenas.pop();
        return ret;
    }*/
    if (result_memory_arenas.try_pop(ret.arena)) {
        return ret;
    }
    ret.arena = std::make_shared<Memory::Arena>();
    return std::move(ret);
}

我使用的代码相当小。

Concurrency::concurrent_vector<Wide::Parser::NamespaceAST*> ASTs;
Concurrency::parallel_for_each(filenames.begin(), filenames.end(), [&](String* ptr) {
    auto arena = ConcurrentGetResultArena();
    ASTs.push_back(parser(lexer(ptr, *arena), *arena));
});

lexerparser都是“纯”函数,不以任何方式或共享状态并发。

系统工作正常,但是当这个函数完成时,内存就会被破坏,我的意思是整个对象包含result_memory_arenas,当队列破坏时,它会试图破坏{{1}有无效指针的s,导致崩溃。但我无法看到问题的来源。我使用了预先提供的并发容器,shared_ptr是线程安全的,并且实际上并行调用的函数是纯粹的。

编辑:其他对象已经死了,因为有趣的是,队列实际上是最后被摧毁的东西。我没有加入队列,而且它们都是有效的shared_ptr。功能完成后,它们全部有效shared_ptr s 。那么为什么在摧毁队列时,它会破坏一个半身像shared_ptr

再次编辑:我在实现中将其追溯到未初始化的内存错误,这并不会让我感到惊讶。令人惊讶的是,这些东西通过了非POD类的任何测试。

1 个答案:

答案 0 :(得分:0)

再次将此问题追溯到实施错误。微软应该雇用我作为测试人员。