在复制构造函数中释放内存时出现问题

Problems freeing memory in a copy constructor

提问人:bko00 提问时间:1/13/2022 最后编辑:bko00 更新时间:1/13/2022 访问量:185

问:

我有这个父类

class Monster 
{
    char* nume;
    double hp;
    float* dmgAbilitati;
    int nrAbilitati;
}

使用此复制构造函数

Monster(const Monster& src)
    {
        if (nume != nullptr)
            delete[] nume;
        this->nume = new char[strlen(src.nume) + 1];
        strcpy_s(this->nume, strlen(src.nume) + 1, src.nume);
        this->hp = src.hp;
        this->nrAbilitati = src.nrAbilitati;
        if (dmgAbilitati != nullptr)
            delete[] dmgAbilitati;
        this->dmgAbilitati = new float[this->nrAbilitati];
        for (int i = 0; i < this->nrAbilitati; i++)
            this->dmgAbilitati[i] = src.dmgAbilitati[i];
    }

我问是否必须使用这些语句

if (nume != nullptr)
            delete[] nume;
if (dmgAbilitati != nullptr)
            delete[] dmgAbilitati;

因为我试图重载这个子类中的前/后增量运算符

class giantSpider : private Monster
{
    int durataStun;

.
.
.
const giantSpider operator++(int)
    {
        giantSpider aux(*this);
        durataStun++;
        return aux;
    }
}

它会抛出一个异常,如下图所示(有时有效), 如果我不包括这些陈述,一切都很好。

我正在使用这个构造函数来初始化参数

Monster(const char* nume, double hp, int nrAbilitati, float* dmgAbilitati)
    {
        if (nume == nullptr)
            throw new exception("Nume invalid!\n");
        else
        {
            this->nume = new char[strlen(nume) + 1];
            strcpy_s(this->nume, strlen(nume) + 1, nume);
        }
        if (hp <= 0)
            throw new exception("Hp invalid!\n");
        else
            this->hp = hp;
        if (nrAbilitati <= 0 && dmgAbilitati == nullptr)
            throw new exception("nrAbilitati invalid sau dmgAbilitati invalid!\n");
        else
        {
            this->nrAbilitati = nrAbilitati;
            this->dmgAbilitati = new float[nrAbilitati];
            for (int i = 0; i < nrAbilitati; i++)
                this->dmgAbilitati[i] = dmgAbilitati[i];
        }
    }

对于孩子:

giantSpider(const char* nume, double hp, int nrAbilitati, float* dmgAbilitati, int durataStun)
        :Monster(nume, hp, nrAbilitati, dmgAbilitati)
    {
        if (durataStun <= 0)
            throw new exception("Numar introdus invalid!\n");
        else
            this->durataStun = durataStun;
    }

这是主要的:

float v1[] = { 125,234.22,8643.3 };
giantSpider  g2("Ana", 1000, 3, v1, 3);
cout << g2 << ++g2 << g2++ ;

我已经使<<运算符过载。

https://i.stack.imgur.com/u6kiz.png

C++ OOP 复制构造函数 delete-operator

评论

1赞 HolyBlackCat 1/13/2022
你这样做是为了练习使用new/delete吗?如果没有,您应该使用...std::string
1赞 Evg 1/13/2022
1)如果你这样做,你会得到UB,因为没有初始化。2)调用是安全的。if (nume != nullptr) delete[] nume;numedeletenullptr
0赞 rturrado 1/13/2022
你不应该因为你正在(复制)构造你的对象而释放。numeMonster
0赞 Mad Physicist 1/13/2022
你是否曾经在第一次创建怪物时初始化为非垃圾值?nume
1赞 Drew Dormann 1/13/2022
原始指针通常是不必要的,它们肯定会让许多对 C++ 不是很有经验的人感到困惑。为什么选择使用指针?

答:

3赞 Vlad from Moscow 1/13/2022 #1

这些语句

if (nume != nullptr)
            delete[] nume;
if (dmgAbilitati != nullptr)
            delete[] dmgAbilitati;

没有意义,因为数据成员 和 尚未初始化。更准确地说,这两个内存都没有分配到它们指向的位置。numedmgAbilitati

因此,这些语句调用未定义的行为。