代码之家  ›  专栏  ›  技术社区  ›  jjmcc

调用reset()时,为什么通过unique-ptr创建的内存没有被正确删除?

  •  2
  • jjmcc  · 技术社区  · 7 年前

    我有一个快速接收数据包的应用程序,每次它接收数据包时,都会创建一些对象来处理它们,对于我正在使用的对象创建 std::unique_ptr

    由于某些原因,它们似乎没有得到适当的清理,因为我可以看到应用程序的内存使用量不断上升。

    enter image description here

    我拍了一张快照,看看分配是从哪里来的,和预期的一样

    enter image description here

    下面是创建这些 PacketIn PacketHeader 物体

    while (!server->BufferEmpty()) {
            std::shared_ptr<Stream> inStream = std::make_shared<Stream>();
            std::vector<unsigned char> buffer = inStream->GetBuffer();
    
            std::size_t n = server->receive(boost::asio::buffer(buffer),
                boost::posix_time::milliseconds(-1), ec);
    
            if (ec)
            {
                std::cout << "Receive error: " << ec.message() << "\n";
            }
            else
            {
                std::unique_ptr<IPacketIn> incomingPacket = std::make_unique<IPacketIn>();
    
                incomingPacket->ReadHeader(inStream);
                std::cout << "Received a buffer! ";
                //std::cout.write(buffer, n);
                std::cout << "\n";
    
                incomingPacket.reset();
            }
    
            ++packetsRead;
    
            inStream.reset();
    
    }
    

    class IPacketIn {
    public:
        IPacketIn() {
            m_packetHeader = std::make_unique<PacketHeader>();
        }
    
        ~IPacketIn() {
            m_packetHeader.reset();
        }
    
        void ReadHeader(std::shared_ptr<Stream> stream) {
            m_packetHeader->ReadHeader(stream);
        }
    
    private:
        std::unique_ptr<IPacketHeader> m_packetHeader;
    };
    

    包装头

    class PacketHeader : public IPacketHeader {
    public:
        PacketHeader() {
    
        }
    
        ~PacketHeader() {
    
        }
    
        void ReadHeader(std::shared_ptr<Stream> stream) override {
            //m_uuid = stream->ReadUUID(10);
            //m_timestamp = stream->ReadInt64();
            //m_packetId = stream->ReadShort();
        }
    
    private:
        std::string m_uuid;
        //long m_timestamp;
        //unsigned short m_packetId;
    

    unique_ptr 但它是真的删除了它创建的内存,还是我遗漏了什么?


    编辑

    独特的 因为我试着用 new delete 同样的问题。

    我注意到问题发生在 类具有成员变量

    std::string m_uuid;
    long m_timestamp;
    unsigned short m_packetId;
    

    删除这些变量后,问题不再出现。

    std::string uuid; . 当这个出现在 包装头

    2 回复  |  直到 7 年前
        1
  •  4
  •   user7860670    7 年前

    事实证明 PacketHeader IPacketHeader 它缺少一个虚拟的析构函数。所以 std::unique_ptr<IPacketHeader> 无法正确执行清理。

        2
  •  3
  •   Martin Bonner supports Monica    7 年前

    请注意,这两个调用 reset 需要-在这两种情况下都将调用指针的析构函数,这将删除内存。

    重用最近释放的内存-以减少释放错误后使用的影响。

    试着用valgrind看看你有没有 实际的

    编辑 : VTT 只是监视进程内存,但使用VS memory profiler(这与valgrind非常相似)。