Сегфо с вектором указателей на векторы - PullRequest
3 голосов
/ 29 августа 2011

Я сузил задачу до этой строки:

    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(); может привести к segfault, я что-то упускаю? Также, если вам нужна дополнительная информация, я могу ее добавить.

РЕДАКТИРОВАТЬ: Я только что понял, что было не так , я использую тот же индекс для adjlist, что я для nets, строка

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

должно быть:

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

РЕДАКТИРОВАТЬ: После перехода через отладчик, я заметил, что в конструкторе Ensemble, nets.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;
        }
    }

Этот конструктор вызывается, когда я создаю экземпляр переменной ensemble в моей 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 ]

3 голосов
/ 29 августа 2011

Проблема, вероятно, одна из следующих

  • Ссылка DDNetwork* в nets[i] неинициализирована, что вызывает ошибку при доступе к участникам.
  • Размер nets и каждый экземпляр adjlist не синхронизируются, что приводит к недействительности одного из смещений

Не могли бы вы опубликовать код, который добавляет DDNetwork* экземпляров в переменную nets?

0 голосов
/ 30 августа 2011

Я обнаружил источник segfault случайно, я делал некоторую грубую отладку, потому что GDB не имел информации о моем файле main.cpp, и чтобы распечатать nets.size(), мне пришлось временно сделать vector<DDNetwork*> nets public, после этого я понял, что программа перестала работать с ошибками.Я подумал, что это может быть связано с различием private / public, но когда я переместил строку

public:
    vector<DDNetwork*> nets;
private:

в строку

public:
private:
    vector<DDNetwork*> nets;

, программа все еще не делала 't segfault, поэтому я попытался переместить строку vector<DDNetwork*> nets; туда, где она была раньше, полностью ниже всех других объявлений методов и членов, как раз перед закрывающей скобкой };, и программа начала сегрегировать, как и раньше,Что это за местоположение строки vector<DDNetwork*> nets;, которая вызывала segfault?

0 голосов
/ 29 августа 2011

Есть две возможности.Либо не существует new DDNetwork с индексом nets[i], либо adjlist[i] не было создано.

Чтобы иметь квадратный вектор векторов, необходимо правильно изменить их размер:

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

... только тогда вы можете их проиндексировать.В качестве альтернативы вы можете push_back правильные значения.

Также обратите внимание, что вы используете тот же индекс для массива nets и массива adjlist, не зная, было ли это предназначено.

...