Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在调用reset()时,通过unique_ptr创建的内存没有被正确删除?_C++_Memory_Unique Ptr - Fatal编程技术网

C++ 为什么在调用reset()时,通过unique_ptr创建的内存没有被正确删除?

C++ 为什么在调用reset()时,通过unique_ptr创建的内存没有被正确删除?,c++,memory,unique-ptr,C++,Memory,Unique Ptr,我有一个快速接收数据包的应用程序,每次它接收数据包时,都会创建一些对象来处理它们,对于对象创建,我使用的是std::unique_ptr 由于某些原因,它们似乎没有得到适当的清理,因为我可以看到应用程序的内存使用率不断上升 我拍了一张快照,看看分配是从哪里来的,这和预期的一样 下面是创建这些PacketIn和PacketHeader对象的代码 while (!server->BufferEmpty()) { std::shared_ptr<Stream> i

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

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

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

下面是创建这些
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();

}
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;
删除这些变量后,问题不再发生

我已经把它缩小为
std::string uuid。当
PacketHeader
类中存在此项时,它会导致内存上升,但当它被删除时,它是正常的。为什么会这样


当对象被销毁时,它们是否没有被删除?

是的,它正在删除内存

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

请注意,监视进程内存是判断内存是否泄漏的一种非常不可靠的方法。在某种程度上,系统库经常尝试不重用最近释放的内存,以减少释放bug后使用的影响

尝试使用valgrind查看是否存在实际内存泄漏


Edit:澄清了OP不仅仅是监视进程内存,而是使用VS内存探查器(与valgrind非常类似)。

事实证明,
PacketHeader
类实例的所有权是通过指向基类
IPacketHeader
的指针来持有的,而基类
IPacketHeader
缺少虚拟析构函数。因此,
std::unique\u ptr
无法正确执行清理。

为什么要重置它?不需要调用reset-在声明ptr的块结束后,它将从堆栈中弹出,并调用其析构函数。(RAII)ReadHeader是否分配?此外,您使用什么工具链?可能有某种泄漏检测工具。@BenjaminMurer只提供成员变量,当对象被删除时,这些变量应该被清除,
Stream
中的函数目前什么都不做。啊,事实上,@CrisLuengo提出了一个非常好的观点。为什么要使用智能指针呢?你可以把它放在堆栈上(如果必须的话,还可以在对象内部分配内存)。查看或
iPacktheader
是否有虚拟析构函数?如果没有,则
std::unique_ptr
将无法正确执行清理。我当前正在使用Windows,valgrind是否不适用于此平台?使用VS memory profiler是检测内存泄漏的可靠方法。你的评论在这方面有误导性。@VTT啊!我不知道这是VS内存分析器中的一个图形。我认为它来自于系统监视器(它只报告进程内存)。我会更新。
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;
std::string m_uuid;
long m_timestamp;
unsigned short m_packetId;