2016-09-24 126 views
1

提供默認構造函數參數時給出分段錯誤**編輯:默認構造函數不會導致問題。我在下面說明了原因。我已經標記並投票結束這個問題,對於現在有這個職位的任何人有任何歉意。 **vector <pair <int,unordered_set <int> >>爲對

int n = numCourses; 
vector<pair<int, unordered_set<int>>> graph(n, make_pair(0, unordered_set<int>())); // pair of how many edges go in, and set of its neighbors. 
// We have to find our leaves: 
bool leaf[n]; 
for(int i = 0; i < n; i++){ 
    leaf[i] = true; 
} 

for(auto p : prerequisites){ 
    graph[p.first].first++; 
    graph[p.first].second.insert(0); 
    leaf[p.second] = false; 
} 

vector<int> leaves; 
for(int i = 0; i < n; i++){ 
    if(leaf[i]) 
     leaves.push_back(i); 
} 

我試圖構建有一些不錯的性能DAG圖不起作用的代碼。我想在圖中提供一個默認的構造函數參數,使用make_pair將右值定義賦予圖的第二個參數。第一個參數是矢量的大小。我想傳遞一個右值,其中對的第一個值是0,所以我知道當我在graph[p.first].first++中增加時它是0。

我試過這個,當它到達graph[p.first].second.insert(0)時,它會拋出一個段錯誤,但我不是100%確定它爲什麼會發生。

,它工作

int n = numCourses; 
vector<pair<int, unordered_set<int>>> graph(n); // NO MORE DEFAULT RVALUE 
// We have to find our leaves: 
bool leaf[n]; 
for(int i = 0; i < n; i++){ 
    leaf[i] = true; 
} 

for(auto p : prerequisites){ 
    graph[p.first].first++; 
    graph[p.first].second.insert(0); 
    leaf[p.second] = false; 
} 

vector<int> leaves; 
for(int i = 0; i < n; i++){ 
    if(leaf[i]) 
     leaves.push_back(i); // This causes a segfault if I don't change it. 
} 

所以這個問題實際上是上線graph[p.first].second.insert(0)之後的代碼。這是我的布爾數組引起的問題。對困惑感到抱歉!我已經標記這個帖子被mods刪除。

謝謝!

編輯:下面我增加了一些可運行情況: 不會導致段錯誤:https://ideone.com/EdmSva 確實會導致段錯誤:https://ideone.com/GHQfog

這是由於布爾數組訪問越界。我應該撿起來的,但我試圖用一些打印語句來查看段錯誤發生的位置。它是在線後,我猜測緩衝區stdout沒有刷新時發生段錯誤,因此該行之前也沒有顯示打印。我不會使用print來二進制搜索段錯誤 - 這裏學到了一個寶貴的教訓。

+0

誰剛剛在主題標題上打字錯誤 - 謝謝!一大早,我還沒有喝咖啡,哈哈:) – OneRaynyDay

+0

什麼讓你覺得第二個,你的話,「未定義的行爲 - 我知道」爲事實?如果你不提供一個參數,那麼大小的向量將使用一個值初始化的參數。因爲你的意思是0和空集爲每一對。這不是你想要的嗎?可以複製/粘貼/編譯以展示您的問題的實際[最小,**完整**,可驗證的示例](https://stackoverflow.com/help/mcve)將對您的問題有很長的路要走。 'leaf'的非標準VLA對你沒有任何好處,我們只能猜測你的*真實*問題。如果我,我會通過valgrind發送這個。 – WhozCraig

+0

@WhozCraig你說得對,我很抱歉。我在腳註中提供了一個MVCE(儘管它已經不重要了),我將在未來這樣做。我做了一些嘗試來調試程序,我認爲這是問題(儘管我錯誤地認爲)。 – OneRaynyDay

回答

2

是的,你錯過了一些東西 - segfault與的初始化無關,它的工作原理與預期的一樣。簡單的例子來看看:

#include <iostream> 
#include <vector> 
#include <unordered_set> 
using namespace std; 

int main() { 
    // your code goes here 
    int n = 5; 
    vector<pair<int, unordered_set<int>>> graph(n, make_pair(0, unordered_set<int>())); 
    graph[0].first = 1; 
    graph[1].second.insert(5); 
    graph[1].second.insert(6); 
    for (auto&& p : graph) { 
     std::cout << p.first << " " << p.second.size() << std::endl; 
    } 
    return 0; 
} 

輸出(或者在這裏運行:https://ideone.com/kSVSnA):

1 0 
0 2 
0 0 
0 0 
0 0 

別的東西是錯誤的一些代碼中的不確定的行爲,並省略位:)

+0

啊好的 - 謝謝!我將檢查根本原因並對此問題進行編輯。 :) – OneRaynyDay

相關問題