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 innets[i]
is uninitialized causing a segfault when you access the members. - The size of
nets
and each instance ofadjlist
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?
精彩评论