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

时间:2016-01-13 12:39:25

标签: c++ memory memory-management memory-leaks copy-constructor

我试图阅读许多解决方案,以便在复制构造函数中发生内存泄漏,但我仍然没有解释如何解决它。

例如,我有一个“Person”类,它具有那些mambers和函数(头文件):

#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();
};

在这个程序中我试图将“对象”输入到Vector,而Person和Vector继承自Object。 在这两个复制常量中我都有内存泄漏问题(该程序工作正常)。

例如,在这段代码中我得到了所有这5个char数组的内存泄漏。我在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;
}

人类是:

#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;
}

我很感谢你的帮助!!

4 个答案:

答案 0 :(得分:3)

你没有内存泄漏。你有一个完整的,破坏内存,未定义的行为:

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

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

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

在您担心复制构造函数发生任何泄密之前,您需要在其他地方修复一系列问题。

答案 1 :(得分:3)

在main()中,tmp char数组不会被删除,这是我看到的第一次内存泄漏。

在Person(char * name)构造函数中,您在

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

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

如果使用std :: string类,至少可以避免删除和删除之间的混淆[]

答案 2 :(得分:1)

在main()中,你准备你的c,你分配5个char缓冲区,永远不会释放

也(不是说std​​ :: string会帮助你处理你的字符串),摆脱不必要的“this-&gt;”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);
}

答案 3 :(得分:-1)

删除时存在一些问题。

在您的主要内容中,首先必须删除temp;在第二口井中不要使用它,使用delete [] persons

在你的拷贝构造函数中不要使用delete this->p_name,这是不正确的。

首先,你必须将指针设置为null,因此p_name = NULL,然后使用setters和getters,对于你的值构造函数也是如此。

在析构函数中,在删除之前测试p_name是否存在。