【问题标题】:destructor deletes contents of pointer析构函数删除指针的内容
【发布时间】:2021-04-04 02:05:27
【问题描述】:

我正在尝试将数组作为类的一部分。数组应该是可变大小。在我的代码中,数组应该由某个函数赋予可变大小的内容,然后将其视为类的成员。我的代码没有运行,我可以将问题归结为几行代码。

在此示例中,我将数组保存在指针“dptr”中,因此它可以由函数初始化为可变大小,然后作为类成员访问。

在我将指针内容放在 void 中之后,我可以只调用一次,之后我在访问它时得到的只是某种奇怪的,几乎是随机的数字。

class x 
{
public:
   double* dptr;

void void_()
   {
       double d[] = { 2., 3., 4. };
       dptr = d;
   }
};


int main() 

{
   x x_;
   x_.void_();

   int index = 0;
   std::cout << x_.dptr[index] << std::endl; // works perfectly fine for any index ( outputs 2 )

   std::cout << x_.dptr[index] << std::endl; // outputs something random ( outputs 6.95241e-310 )
}

我猜想在void结束后调用双“d”的析构函数并删除指针指向的内容。

有没有办法解决这个问题,例如,不允许调用析构函数?

【问题讨论】:

  • 走简单的路,用向量代替。
  • 查看stackoverflow.com/questions/4570366/… 以了解指针的情况。但切换到向量是解决此问题的最佳途径。
  • 一旦void_ 返回,它的本地数组d 被销毁。指向数组的指针保存在其他地方这一事实无关紧要,它仍然被破坏,并且从那时起引用该指针results in demons flying out of your nose。你看到“奇怪”的随机数的原因是因为这就是鼻恶魔所做的。不,没有办法防止d 被破坏,C++ 不能这样工作。
  • “工作得很好”。事实上,你已经在 UB 领域,而且它似乎可以工作(可能是 UB 的输出)。

标签: c++ class pointers destructor member


【解决方案1】:

干净的方法是使用std::vector 并在调用构造函数时初始化成员:

struct x {
    std::vector<double> d;
    x() : d{2.,3.,4.} {}
};

避免调用描述符的方法是动态创建数组。但是,在这种情况下,x 应该跟随 rule of 5

【讨论】:

    【解决方案2】:

    不,您一直在使用动态分配的指针并向类添加析构函数:

    class x 
    {
    public:
       double* dptr;
    
    x()
      {
        dptr = nullptr;
      }
    x(const &x) = delete;
    operator=(const &x) = delete;
    
    void void_()
       {
           double d[] = new double[3]
           d[0] = 2.;
           d[1] = 3.;
           d[2] = 4.; 
           dptr = d;
       }
     ~x() 
       {
           if(dptr != nullptr) {
              delete[] dptr;
           }
       }
    };
    

    但是,如果您尝试以这种方式分配数组来做任何实际工作,请考虑改用std::vector。然后所有内部都为您处理,您不必乱用指针。

    【讨论】:

    • 对不起,我不熟悉 5 的规则...你的意思是我应该将复制构造函数、默认构造函数等显式标记为= delete
    • 析构函数中的代码应该是delete [] dptr;。它是用new[] 创建的,所以它必须用delete[] 销毁。
    • 答案更新了这两个建议 - 现在看起来还可以吗?
    • 感谢大家的反馈!今天学到了一些新东西。
    • 您的编辑添加了不必要的测试。 operator deleteoperator delete[] 理解空指针。析构函数中不需要if (dptr != nullptr)
    猜你喜欢
    • 2014-12-30
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 2012-03-13
    • 1970-01-01
    • 2019-03-31
    相关资源
    最近更新 更多