使用unique_ptr作为class成员,为什么会存在内存泄漏?

Use unique_ptr as a class member, Why does it exist memory leaking?

我正在练习unique_ptr的自定义删除器, 根据我对 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的默认删除器执行:

    delete ptr;

在您自己的删除器中,您仅在 class 实例上调用 shutdowndelete 丢失导致内存泄漏。

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

但是恕我直言 shutdown 应该在 A class 的析构函数中调用。那么自定义删除器就没有必要了。

 class A {
    public:
        A(const string& _path) : m_path(_path) {};

        ~A() { 
           if (m_fp)
             shutdown();
        }
        //...
    };