复制构造函数中的内存泄漏

Memory leaks in copy constructor

我看了很多关于copy constructor内存泄露的解决方法,但是还是没明白怎么解决。

例如,我有一个 "Person" class 具有这些成员和函数(头文件):

#include "Object.h"
#include <string.h>
#include <iostream>
using namespace std;
class Person: public Object
{

private:
    char * p_name;
    int  length;
public:
    virtual Object * copy() const;
    virtual void print(ostream & os) const;
    Person(char * name);
    Person(const Person & per);
    ~Person();
};

在这个程序中,我试图将 "Objects" 输入到 Vector,而 Person 和 Vector 继承自 Object。 在两个复制常量中,我都有内存泄漏问题(程序运行良好)。

例如,在这段代码中,我得到了所有这 5 个字符数组的内存泄漏。我在 Vector 内存泄漏方面也有更多问题,但让我们从 main 中的这个简单代码开始(char 数组发生 5 次内存泄漏):

int main ()
{
    const int SIZE = 5;
    Person* persons[SIZE];
    int i;

    // preparation of name array 
    for (i = 0; i<SIZE; i++) {
        char* tmp = new char[10];
        sprintf(tmp, "P-%d", i);
        persons[i] = new Person(tmp);
    }

    for (i = 0; i < SIZE; i++)
        delete persons[i];

    return 0;
}

人 class 是:

#include "Person.h"
using namespace std;



Object * Person::copy() const
{
    Person * p = new Person(*this);
    return p;
}

void Person::print(ostream & os) const
{
    for (int i = 0; i < this->length-1; i++)
    {
        os << this->p_name[i];
    }
}


Person::Person(char * name)
{
    delete this->p_name;
    this->length = strlen(name)+1;
    p_name = new char[length];
    strncpy(p_name, name, length);
}

Person::Person(const Person & per)
{
    delete[] this->p_name;
    this->length = strlen(per.p_name) + 1;
    this->p_name = new char[this->length];
    strncpy(this->p_name, per.p_name, this->length);
}

Person::~Person()
{
    delete[] this->p_name;
}

非常感谢您的帮助!!

您不仅仅是内存泄漏。您有一个 full-fledged、memory-corrupting、未定义的行为:

Person::Person(char * name)
{
    delete this->p_name;

这是您的构造函数。 p_name class 成员似乎没有以任何方式初始化。你做的第一件事就是尝试 delete 它。

因此,无论随机值 p_name 将包含什么,由于最近的一组宇宙射线撞击保持其初始值的 RAM 电容器,构造函数做的第一件事就是尝试释放pointed-to内存。

在您担心复制构造函数的任何所谓泄漏之前,您需要在其他地方解决一堆问题,例如这个问题。

删除有一些问题。

在你的 main 中,在第一个 while 你必须删除 temp;在第二口井中不要使用它,使用 delete [] persons.

在您的复制构造函数中不要使用 delete this->p_name,那是不正确的。

首先你必须将指针设置为空,所以 p_name=NULL,然后使用 setter 和 getter,对你的值构造函数也是如此。

并且在你的析构函数中,在删除它之前测试 p_name 是否存在。

在 main() 中,您在准备 c 的地方分配了 5 个字符缓冲区,这些缓冲区永远不会被释放

还有(不是说 std::string 这会帮助你处理字符串),摆脱不需要的 "this->"s:

Person::Person(const Person & per)  
{
    delete[] this->p_name;
    this->length = strlen(per.p_name) + 1;
    this->p_name = new char[this->length];
    strncpy(this->p_name, per.p_name, this->length);
}

可能看起来像这样:

Person::Person(const Person & per)
{
    delete[] p_name;
    length = strlen(per.p_name) + 1;
    p_name = new char[length];
    strncpy(p_name, per.p_name, length);
}

在 main() 中,tmp 字符数组没有被删除,这是我看到的第一个内存泄漏。

在 Person(char * name) 构造函数中调用 delete on

Person::Person(char * name)
{
     delete this->p_name;

p_name 未分配,因此行为未定义。而p_name是一个数组,所以应该使用delete[]。

如果使用std::stringclass,至少可以避免delete和delete[]

的混淆