2017-02-25 45 views
0

我有以下的代码:C++分段故障与相同的数组索引

bool *pho=new bool[n]; 
memset(pho, 0, sizeof(bool) * n); 

for (int i = 0; i < m; i++) { 
    int d=2; 

    cout << "i=" << i << ", d="<<d<< endl; 

    pho[d] = true; 
} 

与输入运行n=8结果在下面的输出:

i=0, d=2 
i=1, d=2 
[Segfault] 

我不明白这是为什么发生!由于某种原因,在阵列中设置相同的位置会导致段错误。我已经多次运行该程序,并且它总是生成相同的输出。

用一个调试器遍历代码,当数组被访问时,我可以看到d(索引)的值是2。

我曾尝试使用全局数组和静态全局数组,这两者都导致相同的错误。

我的IDE和编译器有什么问题吗?我正在使用MinGW和Eclipse CDT,并且启用了std/C++ 11选项。

这里是整个源文件,在情况下,程序的其他部分造成的问题:

#include <iostream> 
#include <queue> 
#include <vector> 
#include <unordered_set> 
#include <utility> 
#include <algorithm> 
#include <cstring> 

using namespace std; 

vector<unordered_set<int>> adj; 

static bool *visited; 

pair<int, int> dfs(int node) { 
    if (visited[node]) 
     return make_pair(0, node); 
    pair<int, int> best = make_pair(0, node); 
    for (int neigh : adj[node]) { 
     pair<int, int> alt = dfs(node); 
     alt.second++; 
     best = max(best, alt); 
    } 
    return best; 
} 

int main(int argc, char** argv) { 
    int n, m, def; 
    cin >> n ; 

    cin >> m; 

    bool *pho=new bool[n]; 
    memset(pho, 0, sizeof(bool) * n); 


    int *degrees=new int[n]; 
    memset(degrees, 0, sizeof(int) * n); 

    cout << "n="<<n<<", m="<<m<<endl; 

    for (int i = 0; i < m; i++) { 
     int d=2; 

     cout << "i=" << i << ", d="<<d<< endl; 

     pho[d] = true; 
    } 



    for (int i = 0; i < n - 1; i++) { 
     int a, b; 
     cin >> a >> b; 
     adj[a].insert(b); 
     adj[b].insert(a); 
     degrees[a]++; 
     degrees[b]++; 
    } 

    queue<int> next; 
    for (int i = 0; i < n; i++) { 
     if (degrees[i] == 0) { 
      next.push(i); 
     } 
    } 

    while (!next.empty()) { 
     int node = next.front(); 
     next.pop(); 
     if (pho[node]) 
      continue; 
     for (int neigh : adj[node]) { 
      adj[node].erase(neigh); 
      adj[neigh].erase(node); 
      degrees[node]--; 
      degrees[neigh]--; 
      if (degrees[neigh] == 1) 
       next.push(neigh); 
     } 
    } 

    visited=new bool[n]; 
    memset(visited, 0, sizeof(bool) * n); 

    pair<int, int> pivot = dfs(def); 

    memset(visited, 0, sizeof(bool) * n); 
    pair<int, int> end = dfs(pivot.second); 

    int dist = end.first; //number of edges she only has to walk once 

    int tree = n - 1; //number of edges in tree 

    int otherdist = tree - dist; //number of edges she has to walk twice 

    int total = dist + otherdist * 2; 

    cout << total << endl; 

    return 0; 
} 
+0

解决此类问题的正确工具是您的调试器。在*堆栈溢出问题之前,您应该逐行执行您的代码。如需更多帮助,请阅读[如何调试小程序(由Eric Lippert撰写)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您应该\编辑您的问题,以包含一个[最小,完整和可验证](http://stackoverflow.com/help/mcve)示例,该示例再现了您的问题,以及您在调试器。 –

+0

@πάνταῥεῖ是的,我已经做到了!当数组被访问时,我可以看到'd = 2'。 – AJC

+0

@AJC:还有其他事情正在发生。您很可能会在程序的其他部分调用未定义的行为。 – 3442

回答

0

这些线是错误的:

adj[a].insert(b); 
adj[b].insert(a); 

您需要创建unordered_map实例与ab作为键,然后分别插入ba作为值。如果您需要键值对,则不需要有向量集。

+0

但是这打破了数据结构的目的......我需要能够访问连接到每个“a”的“b”列表。无论如何,你能解释一下它为什么错了吗?代码似乎工作,当我删除任何使用的载体... – AJC

+0

这是错误的'因为你不分配内存到你的载体,然后尝试访问'adj [a]',而没有内存分配来保存索引“a”的东西。如果你想以这种方式继续,那么首先将内存分配给你的向量,然后插入这些元素。 @AJC – Jarvis

+0

我认为C++矢量自动分配。或者我需要使用插入功能? – AJC