2015-10-22 2 views
2

Im beginnger в C++ и попытайтесь создать контейнер класса контейнера, который похож на Vector. этот класс должен работать как вектор для всех типов данных и может использоваться в цикле, основанном на диапазоне. Я написал hpp, но мой наставник говорит, что есть утечка памяти, я думаю, что я удалил всю динамическую память, где может быть проблема?C++: утечка памяти; векторный класс

#include "stdafx.h" 
using namespace std; 
template<class T> 
class Customvector 
{ 
public: 
    Customvector(); 
    ~Customvector(); 
    int size(); 
    int free_capacity(); 
    void add(T& temp); 
    int& operator[](int index); 
    void grow(); 

    class iterator { 
     public: 
      iterator(T* ptr) : ptr(ptr) {} 
      iterator operator++() { iterator i(ptr); ++ptr; return i; } 
      bool operator!=(const iterator & other) { return ptr != other.ptr; } 
      const T& operator*() const { return *ptr; } 
     private: 
      T* ptr; 
     }; 

    iterator begin() const { return iterator(&_elements[0]); } 
    iterator end() const { return iterator(&_elements[0]+_size); } 
private: 
    T* _elements; 
    int _size; 
    int _capacity; 
    int DEFAULT_CAPACITY; 
}; 

template<class T> 
Customvector<T>::Customvector() 
{ 
    DEFAULT_CAPACITY = 4; 
    _capacity = DEFAULT_CAPACITY; 
    _size = 0; 
    _elements = new T[_capacity]; 

} 
template<class T> 
Customvector<T>::~Customvector() 
{ 
    delete[] _elements; 

} 
template<class T> 
void Customvector<T>::add(T& temp) 
{ 
    grow(); //check if the capacity is full, if so,increase capacity by DEFAULt_CAPACITY; 
    _elements[_size++]= temp; 

} 
template<class T> 
int Customvector<T>::size() 
{ 
    return _size; 
} 

template<class T> 
int Customvector<T>::free_capacity() 
{ 
    int free_c = _capacity - _size; 
    return free_c; 
} 


template<class T> 
int& Customvector<T>::operator[](int index) { 
    if (index<0 || index>_capacity) 
    { 
     cout << "index beyond limit" << endl; 
     return _elements[0]; 
    }; 
    return _elements[index]; 
} 

template<class T > 
void Customvector<T>::grow() 
{ 
    if (_capacity == _size) 
    { 
     _capacity += DEFAULT_CAPACITY; 
     T* p = new T[_capacity]; 
     std::copy(_elements, _elements + _size,p); 
     delete[] _elements; 
     _elements = p; 
    }; 

} 
+2

Возможно, вы захотите прочитать о [правилах три, пять и ноль] (http://en.cppreference.com/w/cpp/language/rule_of_three). –

+0

Во-первых, у вас нет деструктора в вашем классе итератора, который, вероятно, там, где вы бы «delete [] ptr' – TriHard8

+0

Кроме того, у вас есть * неопределенное поведение * в вашей функции' operator [] ', если вы передаете незаконный индекс и вектор пуст. Содержимое выделенных вами данных * неопределенно *, и использование его каким-либо образом, кроме инициализации данных, приведет к указанному неопределенному поведению. –

ответ

3

Единственный вытекающей случай, что я могу найти в grow:

... 
    T* p = new T[_capacity]; 
    std::copy(_elements, _elements + _size,p); // may throw an exception 
    delete[] _elements; 
    _elements = p; 
    ... 

Если копирование содержимого элемента бросками, затем _elements все еще указывает на старый массив и новый массив, на который указывает p протечек , Вы можете решить эту проблему с unique_ptr:

std::unique_ptr<T[]> p(new T[_capacity]); 
std::copy(_elements, _elements + _size, p.get()); // it's OK if this throws, unique_ptr will take care of the memory 
delete[] _elements; 
_elements = p.release(); 

Использование unique_ptr для _elements слишком упростили бы некоторые из кода и улучшить правильность.

+0

Я не понимаю, как здесь работает исключение, я имею в виду: std :: copy (_elements, _elements + _size, p); // если здесь выкинуть исключение, он выпрыгнет из цельной области здесь или только этой отдельной строки кода? –

+0

@LiZeng исключения работа здесь так же, как и везде. Когда объект бросается, область действия завершается. И если объект не был захвачен никаким выражением catch, тогда более высокие области рекурсивно выходят до тех пор, пока не будет обнаружен брошенный объект. – user2079303

Смежные вопросы