首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++矢量与内存泄漏

C++矢量与内存泄漏
EN

Stack Overflow用户
提问于 2013-08-05 20:53:06
回答 2查看 23K关注 0票数 4

我在前些时候读到过向量会导致内存泄漏,这取决于它们是如何使用的,但我只想问一问:

代码语言:javascript
复制
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

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

    return 0;
    //Detects memory leaks
}

这个没有检测到任何东西:

代码语言:javascript
复制
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

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

    return 0;
    //No memory leaks detected
}

在清除指针之前,将从向量中删除对象。我记得我读过向量、列表和其他std容器在它们所在的块之后被自动删除,所以在示例1中,我得到内存泄漏,因为内存泄漏函数是在块结束之前调用的,所以向量仍然活着并导致它。

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-05 21:13:43

调用_CrtDumpMemoryLeaks的时间点很重要,因为所有已使用的内存可能还没有释放。例如,在下面的示例中,如果在_CrtDumpMemoryLeaks()超出范围之前调用listPtrs,那么它分配的任何内存都将包含在泄漏内存列表中。

代码语言:javascript
复制
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

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

    _CrtDumpMemoryLeaks();

    return 0;
}

在下面的示例中,listPtrs在调用_CrtDumpMemoryLeaks之前超出了作用域,因此它所分配的任何内存都将被释放,而不会在泄漏内存块中列出。

代码语言:javascript
复制
#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的析构函数。

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;
}
票数 12
EN

Stack Overflow用户

发布于 2013-08-05 21:06:52

在这两段代码中,您已经在堆栈上分配了vector<>。因此,向量的析构函数在超出作用域时将被调用。我不知道你用的是什么检漏器,但如果它在主出口之前检查泄漏,它可能确实能检测到泄漏,但它并不是真正的泄漏。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18067504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档