【发布时间】:2014-11-18 12:24:03
【问题描述】:
这段代码有内存泄漏,我不明白为什么。
每个线程都调用函数 exec。函数 exec 只是创建一个 std::vector 然后删除它。这个向量的长度等于线程的数量,它只被创建和删除一次。
您可以假设这段代码是线程安全的,因为向量仅在创建后才被删除。
class Foo{
public:
Foo(const std::size_t& numThreads):size_(numThreads){}
inline void alloc(){std::call_once(bufferflag_,&Foo::alloc_,this);}
inline void free(){std::call_once(bufferflag_,&Foo::free_,this);}
private:
const std::size_t size_;
std::vector<double>* bufferptr_;
std::once_flag bufferflag_;
inline void alloc_(){bufferptr_ = new std::vector<double>(size_);}
inline void free_(){delete [] bufferptr_;}
};
void exec(Foo& comm){
comm.alloc();
// sync the threads here with some barrier
comm.free();
}
void main(){
Foo comm(10);
std::vector<std::thread> t(10);
for(std::size_t tid=0;tid!=10;++tid) t[tid]=std::thread(exec,std::ref(comm));
for(std::size_t tid=0;tid!=10;++tid) t[tid].join();
}
堆摘要:
退出时使用:104 个字节,2 个块
总堆使用量:23 次分配,21 次释放,分配 3,704 字节
1 个块中的 104(24 个直接,80 个间接)字节在 2 个丢失记录 2 中肯定丢失了
泄漏摘要:
肯定会丢失:1 个块中的 24 个字节
间接丢失:1 块 80 字节
可能丢失:0 个块中的 0 个字节
仍然可达:0 个块中的 0 个字节
抑制:0 个块中的 0 个字节
更新
如果我不使用 call_once 而只是从同一个线程中调用 new 和 delete,则不会出现内存泄漏。
【问题讨论】:
-
也许你需要在删除exec函数中的指针之前调用bufferptr.clear()? 80B 是 sizeof(double) * 10
-
如果我在delete heap之前调用bufferptr_->clear()和泄漏总结是完全一样的。
-
你如何确保
alloc被调用之前free? -
这个程序是一个巨大的竞争条件。
-
在 alloc 和 free 的调用之间,我使用屏障来同步线程。我没有发布完整的代码,因为它变得冗长且可读性差。您可以添加一个冗长的计算,以确保以正确的顺序调用这两个函数或实现一个屏障来同步线程。
标签: multithreading c++11 memory-leaks new-operator delete-operator