2016-04-15 68 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')的索引是未定義的行爲,所以你肯定會導致段錯誤或其他任何事情。 –

相關問題