2016-04-15 2 views
0

Я пытаюсь изучить C++. Я создал векторный класс vec, и я пытаюсь реализовать метод вычисления продукта dot.Ошибка сегментации при попытке доступа к данным, хранящимся в векторе

Он компилируется нормально, но при его запуске возникает ошибка сегментации. Я приколол ссылку x (i) в методе продукта dot в качестве причины, но я понятия не имею, почему. Я понимаю, что это некоторая проблема с неправильным доступом к памяти, но я понятия не имею, что я делаю неправильно и каков будет правильный путь.

Мой векторный класс:

class vec{ 

    private: 
    vector<double> data; 
    int n; // size 

    public: 
    vec (int s) { n = s; data.reserve(n); } 

    double get(int i) { return data[i]; } 
    void set(int i, double val) { data[i] = val; } 
    int size() { return n; } 

    double operator[] (int i) { return get(i); } 
    double operator() (int i) { return get(i); } 

    double dot (vec x) { 
     assert(n == x.size()); 
     int z = 0; 
     for (int i = 0; i < n; i++){ 
      z += data[i] * x(i); 
     } 

     return z; 
    } 

}; 

Я пытаюсь использовать это как так:

int main(int argc, char *argv[]) { 

    vec x = vec(3); 
    x.set(0, 1); 
    x.set(1, 1); 
    x.set(2, 2); 

    vec y = vec(3); 
    y.set(0, 2); 
    y.set(1, 2); 
    y.set(2, 3); 

    double z = x.dot(y); 

} 

ответ

3

Изменить это:

data.reserve(n); 

к этому:

data.resize(n); 

reserve не создает элементы в векторе. Все, что он делает, - это увеличение емкости. Чтобы создать n объектов вверх, вы используете resize.

Также на боковой ноте я предлагаю вам не использовать посторонние переменные, такие как n, чтобы отслеживать размер вектора. Вместо этого используйте функцию vector::size(). Причина в том, что вы рискуете ошибками, если по какой-то причине n не обновлен правильно.

Таким образом, это должно быть вашим конструктор:

vec (int s) : data(s) {} 

и сбросить переменную n члена.

+1

Это было быстро. Благодарю. –

+0

Я удивлен тем, что это превзошло все это. Память готова к использованию, и здесь нет возможности попытаться прочитать представление ловушки из неинициализированной ценности или что-то в этом роде. Это какая-то темная магия. Возможно, оптимизация задерживает (или полностью ускоряет) выделение, поскольку компилятор видит, что вы никогда не создаете никаких элементов, поэтому зарезервированная память «не нужна». –

+0

I _know_ это разрешено; Я говорю, что я удивлен, что это _did_. –

-2

В этой статье:

vec y = vec(3); 
y.set(0, 2); 
y.set(1, 2); 
y.set(2, 3); 

Вы установки индекса 3, который находится вне границ этого вектора. Чтобы исправить это, либо инициализируйте vec длиной 4, либо укажите где-нибудь еще. :)

Вы также должны изменить размер вместо резервирования, но неправильное это не должно вызывать segfault. Это должно просто путать людей.

+2

Нет, я инициализирую индекс 2 значением 3. Изменение резерва для изменения размера фиксировало его. –

+0

Доступ к индексу, который является только 'reserve'd (часть' capacity', но не 'size'), является неопределенным поведением, поэтому вы наверняка _could_ вызывают segfault или что-то еще. –

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