为什么 Valgrind 在此实现中报告内存泄漏?



我有以下一段C++代码,其中我正在尝试执行一个例程:

#include <thread>
#include <unistd.h>
#include <sys/wait.h>
#include <memory>
using namespace std;
static void upload(const string url, const string path){ int sync_status;}
int main(){
bool flag = true;
for(int worker_id = 0; worker_id < 1; worker_id++){
int worker_pid = fork();
if (worker_pid == 0){
while (true){
std::unique_ptr<std::thread> uploader(nullptr);
if (flag){       // This block only occurs once inside while loop
flag = false;
string path = "l", url = "k";
// Valgrind reports the next line
uploader = std::make_unique<std::thread>(upload, url, path);
}
int child_id = fork();
if (!child_id){
// Do something
exit(0);
}
waitpid(child_id, NULL, 0);
if(uploader && uploader->joinable()){
uploader->join();
}
}
// Do something
exit(0);
}
}
return 0;
}

但是 valgrind 似乎总是按如下方式报告此代码:

==16424== 80 bytes in 1 blocks are definitely lost in loss record 2 of 2
==16424==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16424==    by 0x10AA39: std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> > std::thread::_S_make_state<std::thread::_Invoker<std::tuple<void (*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(std::thread::_Invoker<std::tuple<void (*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&) (thread:197)
==16424==    by 0x10A04A: std::thread::thread<void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (thread:126)
==16424==    by 0x109A64: std::_MakeUniq<std::thread>::__single_object std::make_unique<std::thread, void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (unique_ptr.h:825)
==16424==    by 0x109514: main (main.cpp:21)

泄漏背后的原因是什么?我以为这是由于exit()电话,但即使在电话之前加入unique_ptr也无济于事。

你可以在 [basic.start.main] 中找到这句话:

在不离开当前块的情况下终止程序(例如,通过调用函数std​::​exit(int)([support.start.term]((不会破坏任何具有自动存储持续时间([class.dtor](的对象。

因此,您的分叉unique_ptr副本永远不会被销毁。这就是瓦尔格林德报告的泄漏。

并不是说试图销毁unique_ptr的两个副本似乎也是一个好主意。因此,此示例的设计可能存在更深层次的缺陷。

最新更新