如果我不使用 new 关键字,可能会出现内存泄漏吗?

Can I have memory leaks if I'm not using new keyword?

本文关键字:内存 泄漏 new 关键字 如果      更新时间:2023-10-16

我是该语言的新手,对内存泄漏有基本的怀疑。如果我不使用new关键字,是否可能发生泄漏?(即在堆栈中有我的变量,并使用像std::vector这样的数据容器)

我应该担心这个问题吗?

如果是这样的话,有人能给我举一个例子,说明在没有动态分配内存的情况下会造成泄漏吗?

即在堆栈中有我的变量并使用std::vector等数据容器

不,对于std::vector或其他标准容器,您不必担心。

有人能给我举一个例子,说明在没有动态分配内存的情况下会造成泄漏吗?

一个常见的错误是形式为的循环相关智能指针

class Child;
class Parent {
std::vector<std::shared_ptr<Child>> childs;
};
class Child {
std::shared_ptr<Parent> parent;
};

由于共享指针的引用计数器永远不会降到零,因此这些实例永远不会被删除并导致内存泄漏。

关于造成这种情况的原因以及如何避免的更多信息,可以在这里找到

  • 如何使用shared_ptr避免内存泄漏

我认为如果不动态保留内存,就不可能泄漏内存。可能,全局变量不会被释放,但我不会称之为内存泄漏。

然而,与使用关键字new相比,有更多的方法可以动态保留内存。

例如,malloc分配一个内存块。此外,calloc保留内存并将其归零。

您的操作还可以为您提供管理内存的方法。例如,适用于Linux的strdup

您也可以使用智能指针并调用std::make_uniquestd::make_shared。这两种方法都动态分配内存。

对于std::unique_ptr,如果调用release()而忘记删除指针,则可能会发生泄漏。

std::make_unique<int>(3).release(); // Memory leak

对于std::shared_ptr,如果创建循环引用,则可能会发生泄漏。你可以在这里找到更多信息。

此外,当您使用静态变量时,在变量超出范围时不会调用析构函数,而是在执行结束时调用。这并不完全是内存泄漏,因为最终调用了析构函数,但您可能已经分配了一些内存而没有使用。

例如,考虑以下代码:

#include <iostream>
#include <string>
#include <vector>
void f() 
{
static std::vector<int> v;
v.insert(v.begin(), 100*1024*1024, 0);
v.clear();
}
int main()
{
f();
return 0;
}

CCD_ 14不需要释放由矢量分配的存储器。因此,在调用f()之后,您将分配400MB的内存,但只能在f()内部访问。这并不完全是内存泄漏,但它是一种分配的资源,直到最后才会自动释放。

除了其他答案之外,内存泄漏的一个简单来源是外部库。它们中的许多库,特别是C库或类C库,对于它们的数据类型具有类似create_*destroy_*的函数。尽管您从未显式调用new,但发生内存泄漏仍然同样容易。