简体   繁体   English

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

[英]Memory leaks in copy constructor

I have tried to read lots of solutions to memory leaks occur in copy constructor, but i still didnt understans how to solve it. 我已经尝试阅读许多解决方案,以防止复制构造函数中发生内存泄漏,但是我仍然没有理解如何解决它。

For example i have a "Person" class that has those mambers and functions (header files): 例如,我有一个“ Person”类,该类具有这些成员和函数(头文件):

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

In this program Im trying to enter "Objects" to a Vector while Person and Vector inherit from Object. 在此程序中,我试图将“对象”输入到Vector中,而Person和Vector则继承自Object。 In both of the copy const i have memory leak problems (the program is working excellent). 在两个副本const中,我都有内存泄漏问题(程序运行良好)。

For example in this code im getting a memory leaks of all of those 5 char arrays. 例如,在这段代码中,我获得了所有这5个char数组的内存泄漏。 I have more problems also in Vector memory leaks, but lets start in this simple code in the main (that occurs 5 memory leaks of the char array): 我在Vector内存泄漏中也遇到了更多问题,但让我们从主体中的以下简单代码开始(发生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;
}

Person class is: 人类是:

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

I would be thankful for your help!! 我将感谢您的帮助!

You don't have just a memory leak. 您不仅有内存泄漏。 You have a full-fledged, memory-corrupting, undefined behavior: 您有成熟的,内存损坏的,未定义的行为:

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

This is your constructor. 这是您的构造函数。 The p_name class member does not appear to be initialized in any way. p_name类成员似乎没有以任何方式初始化。 And the first thing you do, is you try to delete it. 您要做的第一件事就是尝试delete它。

So, whatever random value p_name will contain, as a result of the most recent set of cosmic rays striking the RAM capacitors that hold its initial value, the first thing the constructor does is try to free the pointed-to memory. 因此,由于最近一组宇宙射线撞击保持其初始值的RAM电容器,无论随机值p_name将包含什么,构造函数要做的第一件事就是尝试释放指向的内存。

Before you can worry about any alleged leaks from your copy constructor, you need to fix a bunch of problems, like this, elsewhere. 在担心副本构造函数可能发生的任何泄漏之前,您需要在其他地方修复诸如此类的一系列问题。

In main(), the tmp char array is not deleted, and that's the first memory leakage I'm seeing. 在main()中,不会删除tmp char数组,这是我看到的第一个内存泄漏。

In the Person(char * name) constructor you call a delete on 在Person(char * name)构造函数中,调用删除

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

the p_name is not allocated, so the behavior is undefined. p_name未分配,因此行为未定义。 And p_name is an array, so delete[] should be used. p_name是一个数组,因此应使用delete []。

if you use the std::string class, you can at least avoid the confusion between delete and delete[] 如果使用std :: string类,则至少可以避免delete和delete []之间的混淆

in main(), where you prepare your c you allocate 5 char buffers, that're never freed 在main()中,在准备c的地方分配5个char缓冲区,这些缓冲区永远不会释放

also (not speaking of std::string which would help you with your string stuff) , get rid of the unneeded "this->"s: 也(不说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);
}

could look like this: 可能看起来像这样:

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

There are some problems with delete. 删除存在一些问题。

In your main, in the first while you have to delete temp ; 首先,您必须先删除temp in the second well just don't use it, use delete [] persons . 在第二口井中,只是不使用它,请使用delete [] persons

In your copy constructor don't use delete this->p_name , that's not correct. 在您的副本构造函数中,不要使用delete this->p_name ,这是不正确的。

At first you have to set the pointer to null so p_name=NULL, and then use setters and getters, same for your value constructor. 首先,必须将指针设置为null,以便p_name = NULL,然后使用setter和getter,与值构造函数相同。

And in your destructor, test if p_name exists before deleting it. 并且在您的析构函数中,在删除p_name之前测试它是否存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM