与向量传染媒介的Segfault指针

时间:2011-08-29 18:49:19

标签: c++ stl vector segmentation-fault

我已将问题缩小到这一行:

    indg = nets[i]->adjlist[i].size();   // indg is in a method of the Ensemble class

上述变量

    vector<DDNetwork*> nets;    // this vector is in the Ensemble class

    int indg;

    class DDNetwork
    {
        friend class Ensemble;
        ...
        public: 
            vector< vector<int> > adjlist;  // the adjacency list of the network
        ...
    };

我不明白为什么indg = nets[i]->adjlist[i].size();会导致段错误,我有什么遗漏?此外,如果您需要更多信息,我可以添加它。

编辑:我刚刚意识到出了什么问题,我使用adjlist的{​​{1}}相同的索引,nets,行

    indg = nets[i]->adjlist[i].size();

应该是:

    indg = nets[i]->adjlist[j].size();

编辑:在单步执行调试器之后,我注意到在Ensemblenets.size() = 10(预期)的构造函数中,但是当调用方法Ensemble::alloc_dev_memory时,nets.size() = 803384 (意外),所以我认为JaredPar的第二个建议可能解释了这个问题。以下是将DDNetwork *实例添加到nets变量中的代码:

    Ensemble::Ensemble(int N, float K, int S, bool seedrand, int ltype, int numNets)
    {
        this->N = N;
        this->K = K;
        this->S = S;
        this->ltype = ltype;
        this->numNets = numNets;

        if(seedrand)
            srand(time(0));

        nets.resize(numNets);    // make a vector of pointers to DDNetwork
        for(int i=0; i < numNets; ++i)
            nets[i] = new DDNetwork(N,K,S,seedrand,ltype);

        // pre-compute the S^k for k=0,1,...,Kmax
        Spow[0]=1;                  // S^0 = 1
        int k=1;
        while(k <= Kmax*2) {
            Spow[k] = S*Spow[k-1];  // S^k = S*(S^(k-1))
            ++k;
        }
    }

当我在main函数中实例化整体变量时,会调用此构造函数:

    // instantiate ensemble of networks
    Ensemble ens(N, K, S, seed_rand, multiedge, numNets);
    // run_the ensemble one time step
    ens.run_gpu();

然后,Ensemble::run_gpu调用Ensemble::alloc_dev_memory,然后调用nets[i]->adjlist[j].size()时,就会收到分段错误。

nets引用如何未初始化?

3 个答案:

答案 0 :(得分:3)

问题可能是以下之一

  • DDNetwork*中的nets[i]引用未初始化,导致访问成员时出现段错误。
  • nets的大小和adjlist的每个实例未保持同步,导致其中一个偏移无效

您可以发布将DDNetwork*个实例添加到nets变量的代码吗?

答案 1 :(得分:0)

有两种可能性。索引DDNetworknets[i]尚未创建 adjlist[i]

要获得矢量的方形矢量,您需要正确调整它们的大小:

adjlist.resize( MAX );
for (int i = 0; i < MAX; ++i)
  adjlist[i].resize( MAX );

... 然后你可以索引他们。或者,您可以push_back正确的值。

另请注意,对于网络数组和adjlist数组使用相同的索引,不确定是否有意。

答案 2 :(得分:0)

我偶然发现了段错误的来源,我正在做一些粗略的调试,因为GDB没有关于我的main.cpp文件的信息,为了打印nets.size(),我不得不暂时制作vector<DDNetwork*> nets公众,在这之后,我意识到程序不再是段错误了。我认为这可能与private / public区别有关,但当我移动线时

public:
    vector<DDNetwork*> nets;
private:

public:
private:
    vector<DDNetwork*> nets;

行,该程序仍然没有段错误,所以我尝试将行vector<DDNetwork*> nets;移回原来的位置,一直到所有其他方法和成员声明之下,就在关闭大括号之前};,程序开始像以前一样进行分段。导致段错误的行vector<DDNetwork*> nets;的位置是什么?