2012-06-15 3 views
1

Я реализую вектор для упражнения.Использование распределителя для реализации векторного класса: EXC_BAD_ACCESS

Я хочу сделать следующее:

Первоначально выделить 100 элементы без вызова его конструктора. Всякий раз, когда объект добавляется к вектору, он вызывает его конструктор до тех пор, пока вектор не станет слишком большим, чтобы он не мог содержать все объекты. Когда вектор заполнен, я выделяю другие объекты 100 и т. Д.

Это код:

#include <iostream> 
#include <memory> 
#include <exception> 
#include <cstdarg> 

using namespace std; 

class indexOutOfBounds:exception 
{ 
    const virtual char* what() 
    { 
     return "Index out of bounds"; 
    } 
}; 

template <class T> 
class Vector 
{ 
private: 
    T* data; 
    allocator<T> data_all; 
    int length; 
    int _size; 
public: 
    static const int block=100; // the size of a single allocation block 
    Vector() 
    { 
     data=data_all.allocate(block,NULL); 
     length=0; 
     _size=block; 
    } 
    Vector(int n,...) 
    { 
     va_list vl; 
     T temp; 
     va_start(vl, n); 
     for(int i=0; i<n;i++) 
     { 
      temp=va_arg(vl,T); 
      push_back(temp); 
     } 
     va_end(vl); 
    } 
    int size() const 
    { 
     return length; 
    } 
    void push_back(T item) 
    { 
     length++; 
     if(length==_size) 
     { 
      _size+=block; 
      data=data_all.allocate(_size,data); 
     } 
     data_all.construct(&data[length-1],item); 
    } 
    T& operator[] (int i) throw() 
    { 
     if(i<0 || i>=length) 
      throw indexOutOfBounds(); 
     return data[i]; 
    } 
    ~Vector() 
    { 
     for(int i=0; i<length;i++) 
     { 
      data_all.destroy(&data[i]); 
     } 
     data_all.deallocate(data,_size); 
    } 
}; 

int main(int argc, char** argv) 
{ 
    Vector<int> v(1,0); 
    cout << v[0] << endl; 
    return 0; 
} 

я получаю исключение при попытке печати v[0]:

EXC_BAD_ACCESS (код = 1, адрес = 0x0)

Может быть &v[0] is NULL, но я не могу понять причину. Если я не использую конструктор с va_list и я просто пишу главным образом:

int main(int argc, char** argv) 
{ 
    Vector<int> v; 
    v.push_back(1); 
    cout << v[0] << endl; 
    return 0; 
} 

Я не получаю никаких исключений. Может кто-нибудь объяснить, почему?

ответ

4

Наиболее вероятной причиной является то, что в конструкторе с переменными аргументами вы не инициализируете length или _size. Это означает, что эти значения могут быть любыми, когда вы вызываете push_back.

Если вы запустили приложение в отладчике и изучили эти переменные, это было бы очевидно. Я рекомендую, чтобы в следующий раз, когда у вас случился какой-то сбой, запустите его в отладчике и сначала попробуйте выяснить, прежде чем спрашивать здесь.

3

Ваш конструктор Vector(int n,...) не выделяет память. Не инициализирует length, _size. Затем вы сразу вызываете push_back() от Vector(int n,...) конструктора. Когда он называет push_back, проверка if(length==_size) не будет работать так, как предполагалось, поскольку в нем есть значения нежелательной почты.

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