内存泄漏预防C++(我是对的还是错的?)

Memory leak prevention C++ (Am I right or wrong?)

本文关键字:泄漏 C++ 内存      更新时间:2023-10-16

我在互联网上搜索了好几个小时,并想出了这些步骤来防止内存泄漏(不使用智能指针和高级工具)。如果以下调查结果有任何问题,请告诉我。。。提前谢谢。

  1. 对于每个新的应该有一个删除
  2. 如果new在类中,那么将delete放入析构函数将负责动态分配的内存
  3. 如果您从main中的类foo中创建一个新的对象obj,那么在中您必须显式删除obj
  4. 如果你有多维动态数组,你必须删除这两个级别。(我有点不确定这是否安全……我以为只删除一个ptr就可以了,但经过仔细思考,我认为它是一个动态数组的动态数组,应该将每个数组单独视为一个动态阵列)

例1。

char *ptr;
ptr = new char[size];
// Some Code here
delete ptr;

ex2。

//foo.h
class foo { 
private:
    char * ptr;
public
    foo();
    ~foo();
};
// foo.cpp
foo::foo()
{
    ptr = new char[100];
    for (int i = 0; i < 100; i++)
        ptr[i] = i;
}
foo::~foo()
{
    delete ptr;
}

ex3。

//main.cpp   foo class stays the same as ex 2.
int main()
{
    foo obj = new foo();
    // Some code here
    delete obj;
    return 0;
}

ex 4。

//foo.h
class foo {
private:
    char ** ptr;
public
    foo();
    ~foo();
};
//foo.cpp
foo::foo()
{
    ptr = new char[100];
    for (int i = 0; i < 100; i++)
        ptr[i] = new char[100];
    for (int i = 0; i < 100; i++)
        for (int j = 0; j < 100; j++)
            ptr[i][j] = i;
}
foo::~foo()
{
    for (int i = 0; i < 100; i++)
        delete ptr[i];
    delete ptr;
}

以下是您在自己管理内存时需要注意的一些提示:-

首先也是最重要的是:-

1) 始终将delete与new一起使用,将delete[]与new[]一起使用。将它们混合使用会导致未定义的行为。

2) 永远不要组合malloc/delete或new/free。

对于你的问题"如果你有多维动态数组,你必须删除两个级别。"是的,你必须照顾好他们。

您提到的内容是正确的,即无论何时在堆中分配内存,都必须显式删除内存。尽管你错过了围绕RAII的一个重要方面。假设有一个函数,您在其中负责分配/解除分配。

void fun ()
{
 1) int* ptr;
 2) ptr = new int;   //allocated memory.
 3) ...              //do something with ptr.
 4) delete ptr;     //done with ptr now delete it.
}

现在,通过删除使用new分配的内存,您做得很好。然而,程序执行甚至可能无法达到您的删除。(在步骤#3中抛出异常的情况下)。这种情况将构成内存泄漏。

为了解决这些问题,我们有基于RAII概念的智能指针。只要超出范围,它们就会自动删除所引用的内存,这意味着您不需要负责内存管理。

  1. 对于每个新的应该有一个删除

是的。更准确地说:每个new都必须有一个匹配的delete,每个new[]都必须有匹配的delete[]

  1. 如果new在类中,那么将delete放入析构函数将负责动态分配的内存

您还应该注意通过复制构造函数或赋值进行复制时应该发生什么,除非您明确禁止这些操作。看什么是三条规则?了解更多详细信息。

  1. 如果您从main中的类foo中创建一个新的对象obj,那么在中您必须显式删除obj

参见1。?

  1. 如果你有多维动态数组,你必须删除这两个级别。(我有点不确定这是否安全……我以为只删除一个ptr就可以了,但经过仔细思考,我认为它是一个动态数组的动态数组,应该将每个数组单独视为一个动态阵列)

是的,如果您使用的是原始指针,那么无论间接寻址级别有多少,您都必须注意正确的内存管理。


我最后的建议是,不要为这些问题而烦恼,而是使用<memory>智能指针和标准c++容器提供的东西。

不要直接使用new/delete,除非你100%确定你在做什么,并且你200%确定你真的需要这样做。


当您询问实际问题时:

(例如2.)deletenew char[] 不匹配

ptr = new char[100];
           // ^^^^^
foo::~foo() {
    delete [] ptr;
        // ^^ put the square brackets there
}

与(例如4)相同