2016-04-15 67 views
0

我正在尝试学习C++。我创建了一个矢量类vec,我试图实现一种计算点积的方法。尝试访问存储在向量中的数据时出现分段错误

它编译得很好,但运行时出现分段错误。我已经将产品方法中的x(i)参考固定为原因,但我不知道为什么。我收集这是关于错误地访问内存的东西,但我不知道我做错了什么,也不知道正确的方式是什么。

我的矢量类:

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

虽然我很惊讶这个segfaulted。内存已经可以使用了,在这里没有机会尝试从未初始化的值或类似的东西读取陷阱表示。这是一些黑暗的魔法。可能的优化会延迟(或完全消除)分配,因为编译器发现您从未实际创建任何元素,因此保留内存“不需要”。 –

+0

我知道它被允许;我说我很惊讶,它_did_。 –

-2

在本节:

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

你设定指数3,这已经超出了向量的界限的。要修复它,要么将vec初始化为长度4,要么索引别的地方。 :)

你也应该调整大小,而不是保留,但得到这个错误不应该导致段错误。它应该混淆人们。

+2

不,我将索引2初始化为值3。 –

+0

访问只有'reserve'd(容量的一部分,但不是'size')的索引是未定义的行为,所以你肯定会导致段错误或其他任何事情。 –

相关问题