2015-10-22 32 views
2

我用C++初學者,嘗試創建類似於Vector的容器類。這個類應該像Vector一樣適用於所有類型的數據,並且可以在基於範圍的for循環中使用。 我寫了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

首先,你沒有一個析構函數中的迭代器類這可能是在那裏你'刪除[] ptr' – TriHard8

+0

此外,你有*未定義行爲*在'運營商[]'功能,如果你在傳遞非法索引和向量是空的。你分配的數據內容是* indeterminate *,並且除了初始化數據外,任何其他方式都會導致未定義的行爲。 –

回答

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