使用unique_ptr作为类成员,为什么它存在内存泄漏



我正在练习unique_ptr的自定义deleter,在我使用unique_ptr的有限经验中,它应该在我的代码中fclose()之后自动调用析构函数,但它没有。我在网上搜索了很长时间,但没有用。请帮忙或试着就这个问题提出一些想法
提前谢谢。

valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./a.out

主要信息:

==6063== HEAP SUMMARY:
==6063==     in use at exit: 40 bytes in 1 blocks
==6063==   total heap usage: 3 allocs, 2 frees, 73,296 bytes allocated
==6063== 
==6063== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6063==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6063==    by 0x10909C: B::Init() (aa.cc:29)
==6063==    by 0x108E82: main (aa.cc:44)
==6063== 
==6063== LEAK SUMMARY:
==6063==    definitely lost: 40 bytes in 1 blocks
==6063==    indirectly lost: 0 bytes in 0 blocks
==6063==      possibly lost: 0 bytes in 0 blocks
==6063==    still reachable: 0 bytes in 0 blocks
==6063==         suppressed: 0 bytes in 0 blocks

我的代码

class A {
public:
A(const string& _path) : m_path(_path) {};
~A() { }
bool start() {
m_fp = fopen(m_path.c_str(), "r");
return m_fp != nullptr;
}
void shutdown() { fclose(m_fp); }
private:
string m_path;
FILE *m_fp;
};
class B {
public:
B(const string &_path) : m_path(_path) { }
~B() { }
void Init() { m_Amember.reset(new A(m_path)); }; // memory leak, why?
bool Start() { return m_Amember->start(); }
private:
struct ResFree {
void operator()(A* arg) {
arg->shutdown();
}
};
string m_path;
unique_ptr<A, ResFree> m_Amember;
};
int main() {
B Instance("kk.txt"); // kk.txt exists
Instance.Init();
if (!Instance.Start()) {
cout << "Client start failed " << endl;
}
return 0;
}

非数组unique_ptr的默认deleter执行:

delete ptr;

在您自己的deleter中,您只能在类实例上调用shutdowndelete丢失,导致内存泄漏。

struct ResFree {
void operator()(A* arg) {
arg->shutdown();
delete arg;
}
};

但是IMHOshutdown应该在A类的析构函数内部调用。那么自定义deleter并不是真正必要的。

class A {
public:
A(const string& _path) : m_path(_path) {};
~A() { 
if (m_fp)
shutdown();
}
//...
};

最新更新