【问题标题】:Problems freeing memory in a copy constructor在复制构造函数中释放内存的问题
【发布时间】:2022-01-12 19:52:23
【问题描述】:

我有这个父类

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

【问题讨论】:

  • 你这样做是为了练习使用new/delete吗?如果没有,你应该使用std::string...
  • 1) 如果您执行if (nume != nullptr) delete[] nume;,您将获得UB,因为nume 未初始化。 2) 在nullptr 上调用delete 是安全的。
  • 您不应该释放nume,因为您正在(复制)构造您的Monster 对象。
  • 第一次创建怪物时,您是否曾将 nume 初始化为非垃圾值?
  • 原始指针通常是不必要的,它们肯定会让许多对 C++ 不太熟悉的人感到困惑。为什么选择使用指针?

标签: c++ class oop copy-constructor delete-operator


【解决方案1】:

这些陈述

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

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

所以这些语句会调用未定义的行为。

【讨论】:

    猜你喜欢
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2019-08-12
    • 1970-01-01
    相关资源
    最近更新 更多