Я создаю класс стека как упражнение, пытаясь изучить некоторые концепции C++ (списки инициализаторов, управление памятью и шаблоны здесь). Я столкнулся с чем-то, что я не могу опустить.Удаление массива элементов указателей, затем перераспределение его
В функции void Stack :: push (const T & item), если я раскомментирую данные удаления []; строка, мой код работает хорошо, когда аргументом шаблона является, например, int или char. Но с std :: string я получаю странные ошибки памяти.
Мое мышление здесь в том, что мне нужен больший массив -> массивы не могут быть изменены -> Я создаю новый -> Я освобождаю память, которая мне нужна для той, которая скоро не понадобится -> Я делаю существующий указатель указывает на новый адрес памяти, где я создаю больший массив.
Теперь, когда я комментирую строку удаления, код работает хорошо даже с std :: string, но я не вижу, почему я не могу безопасно выполнять операции со всеми типами.
Любые идеи будут оценены.
#include <iostream>
#include <stdio.h>
#include <memory.h>
template<class T>
class Stack
{
T* data;
int sz;
public:
//Stack(){sz=0;}
Stack(const std::initializer_list<T>&);
~Stack();
void push(const T&);
T& pop();
void show() const;
};
template<class T>
Stack<T>::Stack(const std::initializer_list<T> &list)
{
sz=0;
data = new T[list.size()];
for (auto i : list) {
data[sz] = i;
++sz;
}
std::cout<< "Created with sz: "<< sz<<std::endl;
}
template<class T>
Stack<T>::~Stack()
{
delete [] data;
}
template<class T>
void Stack<T>::push(const T& item) {
std::cout<<"push "<<item<<std::endl;
T* arr = new T[sz];
memcpy(arr, data, sz*sizeof(T));
//delete [] data;
data = new T[sz + 1];
memcpy(data, arr, sz*sizeof(T));
++sz;
data[sz - 1] = item;
std::cout<<"new size: "<<sz<<", bytes: "<<sz*sizeof(T)<<std::endl;
}
template<class T>
T& Stack<T>::pop()
{
if(sz > 0) {
std::cout<<"pop "<<data[sz-1]<<std::endl;
std::cout<<"new size: "<<sz-1<<std::endl;
return data[--sz];
}
else
return data[0];
}
template<class T>
void Stack<T>::show() const
{
for (int i=0; i<sz; i++) {
std::cout<<data[i]<<" ";
}
std::cout<<std::endl;
}
int main(){
Stack<int> s = {1,2,3,4,5,6,7,8,9,10,11};
s.show();
s.push(12);
s.push(13);
s.push(14);
s.pop();
s.pop();
s.push(15);
s.push(16);
s.show();
Stack<std::string> d = {"one","two","three"};
d.show();
d.pop();
d.push("four");
d.show();
return 0;
}
Calling 'delete []' вызывает деструктор объектов в массиве, но вы не хотите, чтобы их уничтожали, поскольку вы просто перемещаете их. В конце концов деструктор вызывается дважды, что приводит к ошибкам. –
Я был под ложным впечатлением от того, что на самом деле делает delete []. Спасибо за объяснение. –