kohi11 Ответов: 2

Ошибка сброшенной памяти ядра C++


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

Что я уже пробовал:

<pre>#include <iostream>
#include <stdexcept>

template<typename Tip>
class Lista{
    public:
    Lista(){};
    virtual ~Lista(){};
    virtual int returnNumberOfElements()const=0;
    virtual void removeElement()=0;
    virtual void addInFrontOfIndex(const Tip &el)=0;
};

template<typename Tip>
class NizLista:public Lista<int>{
   Tip **niz;
   int numberOfElements,capacity,index;
   public:
   NizLista(){
       capacity=100;
       numberOfElements=0;
       index=0;
       niz=new Tip*[capacity]{};
   }

   ~NizLista(){ for(int i=0;i<capacity;i++) delete niz[i];
   delete[] niz; 
   }
   int returnNumberOfElements()const;
   void removeElement();
   void addInFrontOfIndex(const Tip &el);
};



template<typename Tip>
int NizLista<Tip>::returnNumberOfElements()const{return numberOfElements;}

template<typename Tip>
void NizLista<Tip>::removeElement(){
    if(numberOfElements==0) throw std::logic_error("List empty");
    delete niz[index];
    for(int i=index;i<numberOfElements-1;i++)
        niz[i]=niz[i+1];
    numberOfElements-=1;
}

template<typename Tip>
void NizLista<Tip>::addInFrontOfIndex(const Tip &el){
    if(numberOfElements!=0){
        for(int i=numberOfElements;i>index;i--)
        niz[i]=niz[i-1];
    }
    niz[index]=new Tip(el);
    numberOfElements++;
}



int main() {
NizLista<int> niz;
for (int i(1); i<=5; i++)
	niz.addInFrontOfIndex(i);
{
    NizLista<int> niz2(niz);
    NizLista<int> niz3;
    niz3=niz;
    niz.removeElement();
    std::cout << niz2.returnNumberOfElements();
    std::cout << " " << niz3.returnNumberOfElements() << " ";
}
std::cout << niz.returnNumberOfElements();
    return 0;
}

2 Ответов

Рейтинг:
2

Greg Utas

Похоже, что вы помещаете целые числа в массив, но затем рассматриваете их как указатели в первой строке вашего деструктора. Я думаю, ты хочешь ...

niz=new Tip*[capacity]{}; // not Tip**

РЕДАКТИРОВАТЬ: Теперь я замечаю, что вы проходите мимо указатель к каждому целому числу, когда вы добавляете его в массив. Но целое число исходит из переменной цикла i, что вызовет проблемы при попытке удалить его, потому что это был адрес в стеке.

Соглашение при написании контейнера заключается в том, чтобы он содержал экземпляры <T>, нет <T*> Если контейнер предназначен для хранения указателей, то код с помощью шаблон должен указать это явно.


Рейтинг:
10

CPallini

В вашем коде есть несколько проблем:

Цитата:
для(int i=0;i<capacity;i++) удалить niz[i];

  • Ваш класс удаляет объекты, время жизни которых не контролируется им.


Цитата:
NizLista<int> niz2(низ);
Цитата:
низ3=низ;
  • Ваш класс (сильно) нуждается в нетривиальном конструкторе копирования и операторе присваивания. Значения по умолчанию не подходят (многократное удаление одного и того же указателя).


  • То index переменная-член не имеет никакого использования (и это вредно) использовать последовательно numberOfElements, вместо.


  • Вы не проверяете, есть ли контейнер numberOfElements в capacity ограничьте, прежде чем фактически добавлять новый элемент.