开发者

Segfault with vector of pointers to vectors

开发者 https://www.devze.com 2023-03-31 18:54 出处:网络
I have narrowed down the problem to this line: indg = nets[i]->adjlist[i].size();// indg is in a method of the Ensemble class

I have narrowed down the problem to this line:

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

Where the above variables are

    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
        ...
    };

I don't understand why indg = nets[i]->adjlist[i].size(); would cause a segfault, is there something I am missing? Also if you need more information I can add it.

EDIT: I just realized what was wrong, I am using the same index for adjlist that I am for nets, the line

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

should be:

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

EDIT: After stepping through the debugger, I noticed th开发者_如何学Pythonat in the constructor of Ensemble, nets.size() = 10 (expected), but when the method Ensemble::alloc_dev_memory is called, nets.size() = 803384 (unexpected), so I think that JaredPar's second suggestion might explain the problem. Here is the code that adds DDNetwork* instances into the nets variable:

    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;
        }
    }

This constructor is called when I instantiate the ensemble variable in my main function:

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

And after that, Ensemble::run_gpu calls Ensemble::alloc_dev_memory, then when nets[i]->adjlist[j].size() is called, that's when I receive the segmentation fault.

How would the nets reference get uninitialized?


The problem is likely one of the following

  • The DDNetwork* reference in nets[i] is uninitialized causing a segfault when you access the members.
  • The size of nets and each instance of adjlist is not kept in sync causing one of the offsets to be invalid

Could you post the code which adds DDNetwork* instances into the nets variable?


There are two possibilities. Either there isn't a new DDNetwork at index nets[i] or adjlist[i] hasn't been created.

To have a square vector of vectors you need to resize them properly:

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

...only then can you index them. Alternatively you can push_back proper values.

Note also that you use the same index for the nets array, and the adjlist array, unsure whether that was intended.


I found the source of the segfault by accident, I was doing some crude debugging because GDB didn't have information about my main.cpp file, and in order to print out nets.size(), I had to temporarily make vector<DDNetwork*> nets public, after doing that, I realized that the program didn't segfault anymore. I thought it might have to do with the private/public distinction, but when I moved the line

public:
    vector<DDNetwork*> nets;
private:

to

public:
private:
    vector<DDNetwork*> nets;

line, the program still didn't segfault, so I tried moving the line vector<DDNetwork*> nets; back to where it used to be, all the way below all of the other method and member declarations, just before the closing brace };, and the program began to segfault as before. What is it about the location of the line vector<DDNetwork*> nets; that was causing the segfault?

0

精彩评论

暂无评论...
验证码 换一张
取 消