Почему при использовании Delete [] в c ++ возникает ошибка Trace / Breakpoint? - PullRequest
0 голосов
/ 28 октября 2019

В настоящее время я работаю над созданием «векторного» класса.

template <typename T>
class Vectors{
private:
        int size_;
public:
        int size_;
        T *elements;
        Vector(){
            size_=0;
            T *elements=new T[size_];
        }
        Vector(int size){
            size_=size;
            T *elements=new T[size_];
        }
        void push_back(T amaze){
            //make new temporary pointer;
            T *Temp=new T[size_+1];
            size_=size_+1;
            for(int i=0;i<size_-1;i++)
                {
                    *(Temp+i)=*(elements+i);
                }
            delete[] elements; //Error occurs here
            elements=NULL;
            elements=Temp;
            *(elements+size_-1)=amaze;
        }
}

После запуска отладчика я обнаружил, что существует ловушка трассировки / точек останова, когда программа достигает элементов delete [].

Почему возникает эта ошибка?

Ответы [ 2 ]

2 голосов
/ 28 октября 2019

Включите предупреждения, и вы увидите, что вы инициализируете не элемент elements, а переменную:

T *elements=new T[size_];

Поэтому, когда вы удаляете их, вы в основном пытаетесь удалить сломанный указатель, который имеетни разу не было выделено и нигде нет очков. Это фактически приводит к аварийному завершению программы.

Кстати, вы должны опубликовать фактический код, который вы запускаете, потому что в настоящее время ваше имя класса Vectors, множественное число;но конструкторы называются Vector. Правильный конструктор будет использовать списки инициализатора и будет иметь значение explicit:

explicit Vector(std::size_t size)
: size_(size), elements_(new T[size_])
{
}

Конструктор по умолчанию не должен пытаться выделить массив размера 0. Просто сохраните elements как nullptr.

2 голосов
/ 28 октября 2019

Ваши конструкторы ничего не присваивают члену класса elements. Они присваивают локальным переменным с тем же именем, скрывая члена класса. Таким образом, член класса все еще неинициализирован, когда push_back() пытается delete[] it.

Изменить

T *elements=new T[size_];

на

elements=new T[size_];

Также обратите внимание, что ваш класс делаетне следует правилу 3/5/0 , так как в нем отсутствуют деструктор, конструктор копирования и оператор присваивания копии. И он объявляет член size_ дважды, что не должно компилироваться.

Попробуйте это:

template <typename T>
class Vector{
private:
    int size_;
    int count_;
    T *elements;
public:
    Vector(){
        size_ = 0;
        count_ = 0;
        elements = new T[size_];
    }

    Vector(int size){
        size_ = size;
        count_ = 0;
        elements = new T[size_];
    }

    Vector(const Vector &v){
        size_ = v.size_;
        count = v.count_;
        elements = new T[size_];
        for(int i = 0; i < count_; ++i) {
            elements[i] = v.elements[i];
        }
    }

    ~Vector() {
        delete[] elements;
    }

    void push_back(T amaze){
        if (count_ == size_) {
            T *Temp = new T[size_ * 2];
            for(int i = 0; i < count_; ++i) {
                Temp[i] = elements[i];
            }
            delete[] elements;
            elements = Temp;
            size_ *= 2;
        }
        elements[count_]= amaze;
        ++count_;
    }

    void swap(Vector &other) {
        std::swap(elements, other.elements);
        std::swap(size_, other.size_);
        std::swap(count_, other.count_);
    }

    Vector& operator=(const Vector &v) {
        if (&v != this) {
            Vector(v).swap(*this);          
        }
        return *this;
    }
};
...