我有这段代码的内存泄漏,我不明白为什么。
每个线程都调用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();
}
HEAP SUMMARY:
在退出时使用:2个块中的104个字节
总堆使用量:23个分配,21个释放,3,704个字节分配
1个块中的104(24个直接,80个间接)字节肯定在2的丢失记录2中丢失泄漏概要:
绝对丢失:1个块中的24个字节
间接丢失:1个块中的80个字节
可能丢失:0个块中的0个字节
仍然可以访问:0个块中的0个字节
抑制:0个块中的0个字节
更新
如果不使用call_once而只是调用new并从同一个线程中删除,则没有内存泄漏。
答案 0 :(得分:0)
看看这个修改后的代码:
class Foo
{
public:
Foo(const std::size_t& numThreads) :size_(numThreads) {}
inline void alloc()
{
printf("alloc\n");
std::call_once(alloc_flag, &Foo::alloc_, this);
}
inline void foo_free()
{
printf("free\n");
std::call_once(free_flag, &Foo::free_, this); // Changed from bufferflag
}
private:
const std::size_t size_;
std::vector<double>* bufferptr_;
std::once_flag alloc_flag;
std::once_flag free_flag;
inline void alloc_()
{
printf("once_alloc_!\n");
bufferptr_ = new std::vector<double>(size_);
}
inline void free_()
{
printf("once_free_!\n");
bufferptr_->clear();
delete bufferptr_; // Not delete[] bufferptr_
bufferptr_ = NULL;
}
};
void exec(Foo& comm){
comm.alloc();
// Barrier
comm.foo_free();
}
如果你使用2个不同的once_flag用于alloc和free ,你还可以运行free_()方法。您只使用一个标志这一事实会导致内存泄漏,因为第一个alloc会标记消耗。
要检查内存泄漏,我使用_CrtDumpMemoryLeaks();
,即使我注释掉线程创建/连接例程,我也会得到一些额外的泄漏,但我认为这个std :: vector thrash。希望这有帮助!