Задать вопрос
Dyikot
@Dyikot

Почему вылетает исключение при удалении объекта?

6411407c38a54110630917.png
Метод где хочу удалить
void UseContainer(IContainer<Processor>* items)
	{
		auto random = Random();
		auto item = Processor();
		int itemsAmount = random.GenerateNumber(5, 10);
		std::system("cls");
		
		for (auto i = 0; i < itemsAmount; i++)
		{
			item.GenerateRandom();
			items->Add(item, i + 1);
			std::cout << items->Show(false);
		}

		std::cout << std::endl;

		while (!items->IsContainerEmpty())
		{
			std::cout << items->Show();
			items->Remove();
		}

		std::cout << "\nОчередь пуста!\n";

		delete items;

		std::system("Pause");
	}


Выделяется память так
case QueueMode:
				{
					UseContainer(new Queue<Processor>());
					break;
				}
				case PriorityQueueMode:
				{
					UseContainer(new PriorityQueue<Processor>());
					break;
				}

Полный код
template <typename T>
class Array
{
public:
	Array(const size_t capasity) : _size(0), _capacity(capasity) {}

	virtual ~Array() = default;

	int Size() const { return _size; }

	bool IsEmpty() const { return _size == 0; }

	virtual void Pop() = 0;
protected:
	size_t _size, _capacity;

	virtual void Resize(const int size) = 0;
};

template <typename T>
class IContainer
{
protected:
	virtual void Add(const T& item, const unsigned priority = 0) = 0;

	virtual void Remove() = 0;

	virtual const T& Show(const bool isFront = true) = 0;

	virtual bool IsContainerEmpty() const = 0;

	friend class Menu;

	template<typename Type>
	friend void UseQueue(IContainer<Type>& container);
};

template <typename T>
class Queue: public Array<T> , public IContainer<T>
{
public:
	Queue() : Array<T>(4), _data(new T[_capacity]), _firstItemShift(0) {}

	~Queue() { delete[] _data; }

	void Push(const T& item)
	{
		int size = _size + 1;
		if (size > _capacity) Resize(_size);
		_data[_size] = item;
		_size = size;
	}

	void Pop() override
	{
		if (_size - 1 >= 0)
		{
			_size--;
			_firstItemShift++;
		}	
	}

	T& Front() const { return _data[_firstItemShift]; }

	T& Back() const { return _data[_size - 1]; }
private:
	void Resize(const int size) override
	{
		_capacity *= 1.5;
		auto data = new T[_capacity];

		for (auto i = 0; i < size; i++)
			data[i] = _data[i + _firstItemShift];

		delete[] _data;
		_data = data;
	}

	//IContainer interface

	void Add(const T& item, const unsigned priority = 0) override { Push(item); }

	void Remove() override { Pop(); }

	const T& Show(const bool isFront = true) override { return isFront ? Front() : Back(); }

	bool IsContainerEmpty() const override { return Array<T>::IsEmpty(); }

	using Array<T>::_size;
	using Array<T>::_capacity;
	T* _data;
	int _firstItemShift = 0;
};

template <typename T>
class PriorityQueue : public Array<T>, public IContainer<T>
{
public:
	PriorityQueue() : Array<T>(1), _node(new Node[_capacity]), _level(0) {}

	~PriorityQueue() { delete[] _node; }

	struct Node
	{
		T Data;
		uint32_t Priority;

		Node() :Data(T{}), Priority(uint32_t{}) {}
		Node(const T& data, const unsigned int priority) :Data(data), Priority(priority) {}

		bool operator>(const Node& other)
		{
			return Priority > other.Priority;
		}
		bool operator<(const Node& other)
		{
			return Priority < other.Priority;
		}
	};

	void Push(const T& item, const int priority)
	{
		int size = _size + 1;
		auto node = Node(item, priority);
	
		if (size > _capacity)
		{
			_level++;
			_capacity += 1 << _level;
			Resize(_size);
		}

		if (size > 1) SiftUp(node);
		else if (size == 1)	_node[_size] = node;
		
		_size = size;
	}

	void Pop() override
	{
		_size--;
		if (_size == 0) return;

		int size = _size;

		if (size < _capacity - (1 << _level))
		{
			_capacity -= 1 << _level;
			_level--;
			Resize(_size + 1);
		}

		auto node = _node[0];
		_node[0] = _node[_size];
		_node[_size] = node;

		if (_size > 1) SiftDown();
	}

	T& Top() { return _node[0].Data; }

private:
	const auto TopPriority() { return _node[0].Priority; }

	void Resize(int size) override
	{
		auto node = new Node[_capacity];

		for (auto i = 0; i < size; i++)
			node[i] = _node[i];

		delete[] _node;
		_node = node;
	}

	void SiftUp(Node& node)
	{
		int parent;
		_node[_size] = node;

		for (auto position = _size; position > 0; position = parent)
		{
			parent = position % 2 == 0 ? (position - 2) / 2 : (position - 1) / 2;

			if (Node tempNode;_node[position] > _node[parent])
			{
				tempNode = _node[position];
				_node[position] = _node[parent];
				_node[parent] = tempNode;
			}
			else return;
		}
	}

	void SiftDown()
	{
		int child, left, right, lastNode = _size % 2 == 0 ? (_size - 1) / 2 : (_size - 2) / 2;
		auto TryChangePriority = [this](int child, int parent)
		{
			if (auto node = Node(); _node[child] > _node[parent])
			{
				node = _node[child];
				_node[child] = _node[parent];
				_node[parent] = node;
				return true;
			}
			else return false;
		};

		for (auto parent = 0; parent < lastNode; parent = child)
		{
			left = 1 + parent * 2;
			right = left + 1;
			child = _node[left] > _node[right] ? left : right;

			if(!TryChangePriority(child,parent)) return;
		}

		left = 1 + lastNode * 2;
		right = left + 1;
		child = _size - right == 0 ? left : _node[left] > _node[right] ? left : right;
		TryChangePriority(child, lastNode);
	}

	//IContainer interface

	void Add(const T& item, const unsigned priority = 0) override { Push(item, priority); }

	void Remove() override { Pop(); }

	const T& Show(const bool isFront = true) override { std::cout << TopPriority() << "  "; return Top(); }

	bool IsContainerEmpty() const override { return Array<T>::IsEmpty(); }

	using Array<T>::_size;
	using Array<T>::_capacity;
	Node* _node;
	int _level;
};

struct Processor
{
	Processor(std::string _name = "", double _clockFrequecny = 0, int _coreAmount = 0) :
		Name(_name), ClockFrequecny(_clockFrequecny), CoreAmount(_coreAmount) {}

	void GenerateRandom()
	{
		auto random = Random();
		int randomValue = random.GenerateNumber(1, 15);
		Name = "AMD Ryzen " + std::to_string(random.GenerateNumber(1, 9));
		ClockFrequecny = 3 + (double)(random.GenerateNumber(1, 100)) / 100;
		CoreAmount = randomValue % 2 == 0 ? randomValue : randomValue + 1;
	}

	friend std::ostream& operator<<(std::ostream& os, const Processor& processor)
	{
		os << processor.Name << ": " << processor.ClockFrequecny <<
			" Hz " << processor.CoreAmount << " Cores " << std::endl;
		return os;
	}

	std::string Name;
	double ClockFrequecny;
	unsigned int CoreAmount;
};

class Menu
{
public:
	void Show()
	{	
		enum Status { Disable, Enable };
		enum Mode { QueueMode = 1, PriorityQueueMode = 2, Exit = 3 };
		int mode;
		bool menuAvailable = Enable;
		
		while (menuAvailable)
		{
			std::system("cls");
			std::cout << "Выберете режим работы:\n1.Очередь\n2.Очередь с приоритетом.\n3.Выйти\n";
			std::cin >> mode;
			
			switch (mode)
			{
				case QueueMode:
				{
					UseContainer(new Queue<Processor>());
					break;
				}
				case PriorityQueueMode:
				{
					UseContainer(new PriorityQueue<Processor>());
					break;
				}
				case Exit:
				{
					menuAvailable = Disable;
					break;
				}
				default: break;
			}
		}
	}

private:
	void UseContainer(IContainer<Processor>* items)
	{
		auto random = Random();
		auto item = Processor();
		int itemsAmount = random.GenerateNumber(5, 10);
		std::system("cls");
		
		for (auto i = 0; i < itemsAmount; i++)
		{
			item.GenerateRandom();
			items->Add(item, i + 1);
			std::cout << items->Show(false);
		}

		std::cout << std::endl;

		while (!items->IsContainerEmpty())
		{
			std::cout << items->Show();
			items->Remove();
		}

		std::cout << "\nОчередь пуста!\n";

		delete items;

		std::system("Pause");
	}
};

class Random
{
public:
	int GenerateNumber(int min, int max)
	{
		std::random_device device;
		auto range = std::uniform_int_distribution<int>(min, max);
		return range(device);
	}
private:

};
  • Вопрос задан
  • 113 просмотров
Подписаться 1 Простой 9 комментариев
Решения вопроса 1
maaGames
@maaGames
Погроммирую программы
Нет виртуального деструктора у IContainer, а удалять пытаешься полиморфно.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы