首页 > 解决方案 > 使用模板时获取“删除时触发断点错误”

问题描述

我正在使用视觉工作室。

我有3节课。当我尝试打印Rectangle ABCD时没问题,但是当我将 ABCD 推入Array [rectangle] A并尝试再次打印 ABCD 时,出现“未加载 wntdll.pdb”并继续,它是“触发断点错误!! ”在删除~Rectangle()

我知道这取决于 Rectangle 类中的指针,但无法确定。

`int main(){
    Array<Rectangle>A;
    Rectangle a;
    cout << a;     //It's oke
    A.PushBack(a); // problem here
    cout<<a;
}`
    class Point
    {
    private:
       float _x;
       float _y;
    public:
       float GetX() { return _x; }
       float GetY() { return _y; }
    public:
       Point();
       Point(float, float);
       Point(const Point&);
       ~Point() {};
    public:
       string ToString() const;
    public:
       friend istream& operator>>(istream&, Point*);
       friend ostream& operator<<(ostream&, const Point&);
    };
    Point::Point() {
       _x = 1;
       _y = 1;
    }
    Point::Point(float x, float y) {
       _x = x;
       _y = y; 
    }
    Point::Point(const Point& a) {
       _x = a._x;
       _y = a._y;
    }
    string Point::ToString() const{
       stringstream out;
       out << "( " << _x << "," << _y << " )";
       return out.str();
    }
    istream& operator>>(istream& in, Point* a) {
       cout << "Nhap x: ";
       in >> a->_x;
       cout << "Nhap y: ";
       in >> a->_y;
       return in;
    }
    ostream& operator<<(ostream& out, const Point& a)
    {
       out << a.ToString();
       return out;
    }
    ```


class Rectangle
{
private:
    Point* _topleft;
    Point* _botright;
public:
    void Set_topleft(Point tl) { _topleft = &tl; }
    Point Get_topleft() { return *_topleft; }
    void Set_botright(Point br) { _botright = &br; }
    Point Get_botright() { return *_botright; }
public:
    Rectangle();
    Rectangle(Point*, Point*);
    ~Rectangle();
public:
    string ToString() const;
public:
    friend istream& operator>>(istream&, Rectangle&);
    friend ostream& operator<<(ostream&, const Rectangle&);
};
Rectangle::Rectangle()
{
    _topleft = new Point(0, 2);
    _botright = new Point(3, 0);
}
Rectangle::Rectangle(Point* a, Point* b)
{
    _topleft = new Point(*a);
    _botright = new Point(*b);
}
Rectangle::~Rectangle()
{
    delete _topleft;
    delete _botright;
}
string Rectangle::ToString() const
{
    stringstream out;
    out << "A" << *_topleft << "+" << "D" << *_botright;
    return out.str();
}
istream& operator>>(istream& in, Rectangle& a)
{
    std::cout << "A( x,y ): ";
    in >> a._topleft;
    std::cout << "D( x,y ): ";
    in >> a._botright;
    return in;
}
ostream& operator<<(ostream& out, const Rectangle& a)
{
    out << a.ToString();
    return out;
}
```
    template<class T>
    class Array
    {
    private:
        T* _a;
        int _len;
    public:
        Array();
        ~Array();
    public:
        int length() { return _len; }
        void PushBack(T);
        T GetAt(int);
    };
    template<class T>
    Array<T>::Array() {
        _a = new T[128];
        _len = 0;
    }
    template<class T>
    Array<T>::~Array() {
        delete[] _a;
        _len = 0;
    }
    template<class T>
    void Array<T>::PushBack(T value) {
        if (_len >= 128)
        {
            std::cout << "Array is over size, which is 128\n";
            return;
        }
        _a[_len] = value;
        _len++;
    }
    template<class T>
    T Array<T>::GetAt(int pos) {
        return _a[pos];
    }

    ```



标签: c++ooptemplates

解决方案


您的代码中的问题是,当您PushBackRectangle对象a放入数组时,您会创建该对象的副本。这意味着您只需复制指针_topleft_botright. 因此,在这部分代码中,您有 2 个具有相同指针的对象,因此您尝试delete将相同的内存部分加倍。要解决这个问题,您需要定义自己的复制构造函数,它将在新对象中创建新指针。
还要记住定义自己的移动构造函数或使其对您的类禁用。

Rectangle(const Rectangle &other) 
 {
        if(other._topleft)
           _topleft= new Point(*other._topleft); 
        else
            _topleft = nullptr;
        if(other._botright)
           _botright= new Point(*other._botright); 
        else
            _topleft = nullptr;
 } 

下一个问题是由于 的定义void Array<T>::PushBack(T value)。请将其更改为void Array<T>::PushBack(const T& value). 另外,试试Rectangle(Rectangle&& o) = delete;


推荐阅读