繁体   English   中英

C ++向量和内存泄漏

[英]C++ Vectors and Memory Leaks

我读过某处某时以前, 矢量导致取决于他们是如何使用的内存泄漏,但我想问只是要确定:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

int main()
{
    vector<somePtr*> listPtrs;

    return 0;
    //Detects memory leaks
}

这没有发现任何东西:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

int main()
{
    {
        vector<somePtr*> listPtrs;
    }

    return 0;
    //No memory leaks detected
}

在清除指针之前,正在从向量中删除对象。 我想我记得读过它们所在的块之后会自动删除向量和列表以及其他std容器,所以在示例1中我得到了内存泄漏,因为在块结束之前调用了内存泄漏函数,所以向量还活着并造成它。

我不确定它,但是我已经有一段时间了,因为我认为我读过这个,我只能找到关于没有被删除的对象的问题,只是删除了指针。

这是真的? 如果我使用包含向量和列表的全局类,我会得到内存泄漏吗?

您调用_CrtDumpMemoryLeaks的重要性非常重要,因为所有已用内存可能尚未发布。 例如,在下面的示例中,如果在listPtrs超出范围之前调用_CrtDumpMemoryLeaks() ,则它已分配的任何内存都将包含在泄漏内存列表中。

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

int main()
{
    std::vector<struct Foo*> listPtrs;

    _CrtDumpMemoryLeaks();

    return 0;
}

在下面的示例中, listPtrs在调用_CrtDumpMemoryLeaks之前超出范围,因此它已分配的任何内存都将被释放,并且不会在泄漏内存块中列出。

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

int main()
{
    {
        std::vector<struct Foo*> listPtrs;
    }

    _CrtDumpMemoryLeaks();

    return 0;
}

同样,如果 main返回调用_CrtDumpMemoryLeaks 则应释放由std::vector分配的任何资源。 再次这是因为listPtrs现在已经超出范围并且已经调用了std::vector的析构函数。

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

// Call _CrtDumpMemoryLeaks after main has returned and before program terminates.
struct AtExit
{
    ~AtExit() { _CrtDumpMemoryLeaks(); }
} doAtExit;

int main()
{
    std::vector<struct Foo*> listPtrs;

    return 0;
}

我强烈建议使用智能指针而不是裸指针。 它让它们在冬天保持温暖,你不必担心使用delete

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>
#include <memory>

// Call _CrtDumpMemoryLeaks after main has returned and before program terminates.
struct AtExit
{
    ~AtExit() { _CrtDumpMemoryLeaks(); }
} doAtExit;

int main()
{
    std::vector<std::unique_ptr<struct Foo*>> listPtrs;

    return 0;
}

在这两段代码中,您已在堆栈上分配了vector<> 因此,当向量的超出范围时,将调用向量的析构函数。 我不知道你正在使用什么样的检漏仪,但是如果它在主要出口之前检查是否有泄漏,它确实可以检测到泄漏,但它实际上并不是泄漏。

当你遇到内存泄漏问题时, std::vector析构函数不会对向量中的项调用delete ,尽管它会调用它们的析构函数。 因此vector<int>vector<MyClass>很好,因为向量包含实际对象并将其称为析构函数。 另一方面,如果你有vector<MyClass*> ,你需要小心; 删除向量不会释放与其指向的MyClass对象关联的内存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM