【问题标题】:Destructor crashes when working with pointers in Visual Studio在 Visual Studio 中使用指针时析构函数崩溃
【发布时间】:2021-10-12 12:26:03
【问题描述】:

当我使用指向此类实例的指针时,由于某种原因,它在涉及析构函数时会崩溃。当我不使用指针时它可以工作

最奇怪的部分是它可以在 VC Code 中工作,但不能在 Visual Studio 中工作。

多项式.h

class Polynomial {
private:

    int32_t* coeffs;
    uint32_t deg;

public:

    Polynomial(int32_t* setCoeffs, uint32_t setDeg) {
        deg = setDeg;
        while (setCoeffs[deg] == 0 && deg > 0) deg--;

        coeffs = new int32_t[deg + 1]();
        for (uint32_t i = 0; i <= deg; i++) {
            coeffs[i] = setCoeffs[i];
        }
    }

    ~Polynomial () {
        delete[] coeffs;
    }

    std::string str() {
        std::string out = "";
        for (uint32_t i = deg; i > 0; i--) {
            if (coeffs[i] == 0) continue;
            if (coeffs[i] > 0 && i != deg) out += "+";

            if (coeffs[i] != 1)
                out += std::to_string(coeffs[i]);

            if (i == 1) out += "x";
            else if (i > 1) out += "x^" + std::to_string(i);
        }
        if (coeffs[0] != 0) {
            if (coeffs[0] > 0) out += "+";
            out += std::to_string(coeffs[0]);
        }
        return out;
    }




    friend std::ostream& operator<<(std::ostream& out, Polynomial p) {
        out << p.str();
        return out;
    }
};

main.cpp

#include <iostream>
#include "Polynomial.h"

int main(){
    int32_t* coeffs = new int32_t[3]();
    coeffs[0] = 5;
    coeffs[1] = 4;
    coeffs[2] = 3;
    Polynomial* p = new Polynomial(coeffs, 2);
    std::cout << (*p);
    delete p;
    return 0;
}

我猜这与 Visual Studio 属性有关,但我不知道要更改什么。

【问题讨论】:

  • 您的多项式类至少缺少正确的复制构造函数和复制赋值运算符。或者你可以直接使用std::vector 而不是手动分配数组。
  • 感谢工作!没想到这么重要
  • 这非常重要,因为您重载的&gt;&gt; 运算符的Polynomial 是按值传递的。这至少需要一个适当的复制构造函数。但是,显示的代码中没有任何内容实际上需要newdelete。使用std::vector 将消除对复制构造函数甚至析构函数的需要,因为它将为您正确管理所有内存分配。这就是std::vector 的用途。

标签: c++ visual-studio class pointers


【解决方案1】:

&lt;&lt; 运算符的重载采用其参数按值;因此,在该行中,std::cout &lt;&lt; (*p); 生成了*p副本,并且当输出完成时,该副本被销毁。但是,正如 cmets 中所指出的,您还没有实现正确的复制构造函数,因此编译器提供了一个默认值,它只是复制数据成员的值(包括 int32_t* coeffs 指针成员)。

所以,当输出操作完成,副本被销毁时,coeffs指向的内存被删除;然后,当您要删除 original 时,您会尝试再次删除该 相同 内存 - 因此导致崩溃。

要解决此问题: (a) 实现正确的复制和赋值构造函数,它们会生成coeffs 数据的真实 副本;或 (b) 将参数提供给您的 &lt;&lt; 运算符通过引用,如下所示:

friend std::ostream& operator<<(std::ostream& out, Polynomial& p) { // Pass "p" BY REFERENCE
    out << p.str();
    return out;
}

当然,进行“(b)”更改并不(不应该)意味着您也不能实现“(a)”。你真的应该两者兼而有之;这是复制构造函数的可能实现:

Polynomial(const Polynomial& rhs) {
    deg = rhs.deg;
    coeffs = new int32_t[deg + 1];
    for (uint32_t i = 0; i <= deg; i++) {
        coeffs[i] = rhs.coeffs[i];
    }
}

【讨论】:

    猜你喜欢
    • 2012-03-13
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    相关资源
    最近更新 更多