vector în afara intervalului/verificare interval (Programare, C++, Vector)

Ashton Wiens a intrebat.

utilizator nou aici.Am scris acest cod care creează o rețea cu noduri și folosește un număr aleatoriu pentru a crea muchii între ele. Țin evidența întregului graf ca un vector, fiecare intrare fiind un vector reprezentând un nod ale cărui elemente sunt vecinii săi. Apoi folosește o căutare de adâncime pentru a găsi numărul de componente, care sunt părți separate ale grafului (variabila mea de contorizare). Apoi scot nodul și numărul de vecini cu care este conectat într-un fișier txt. Codul se compilează, dar promptul de comandă îmi dă o eroare:

terminate called after throwing an instance of ‘std::out_of_range’ what(): vector::_M_range_check

Această aplicație a solicitat Runtime-ului să o termine într-un mod neobișnuit.Vă rugăm să contactați asistența…

Deci… ce înseamnă acest lucru și cum îl pot rezolva?

De asemenea, trebuie să țin evidența numărului de noduri din fiecare componentă, aveți vreo idee?

Mulțumesc anticipat, aici este codul meu:

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vector>
using namespace std;

void gengraph(int v, float p, vector <vector <int> >& G);
void DFS(vector <vector <int> > G, int v, vector<int>& M);

int main()
{
    int a = 1000;
    float b = 0.004;
    vector <vector <int> > G;
    gengraph(a,b,G);
    vector <int> M (1000);
    int count = 0;
    int i;
    for (i = 0; i < a; i++)
    {
        if (M[i]==0)
        {
            DFS(G, i, M);
            count += 1;
        }
    }
    ofstream myfile;
    myfile.open ("data.txt");
    for (int l=0; l<1000; l++)
    {
        myfile << "v   len(G[v])
";
    }
    myfile.close();
}
void gengraph(int v, float p, vector <vector <int> >& G)
{
    for (int i = 0; i<1000; i++)
    {  
        for (int j = 0; j<1000; j++)
        {
            int y = rand();
            bool Prob = (y <= p);
            if (i == j)
                continue;
            else
            {
                if(Prob == true)
                {
                    G.at(i).push_back (j);
                    G.at(j).push_back (i);
                }
            }
        }
    }
}
void DFS(vector <vector <int> >& G, int v, vector<int>& M)
{
    M[v]=1;
    for(unsigned int j = 0; j < G[v].size(); j++)
    {
        if (M[j]==0)
        {
            DFS(G, j, M);
        }
    }
}

4 răspunsuri
Moataz Elmasry

Ați creat vectorul > dar acesta are dimensiunea inițială 0.

Acum, când îl accesați folosind M.at(), acesta verifică dacă acest index este în afara limitei și aruncă o excepție dacă este cazul.

definind vectorul ca:

vector<vector<int> > M(1000);

ar trebui să vă rezolve problema.

De asemenea, ar trebui să folosiți gdb sau alt depanator. vă va ușura mult viața.

Comentarii

  • Am încercat să folosesc vector<int> M(1000); dar mi-a dat aceeași eroare. Cum fac să funcționeze debuggerul de pe Codeblocks? –  > Por Ashton Wiens.
  • dacă aveți gdb instalat, atunci rulați programul dvs. astfel: „gdb –args yourprogram your parameters” –  > Por Moataz Elmasry.
  • de asemenea, imprimați fiecare pas pe care îl faceți, pentru a vedea cum apare eroarea și în ce iterație. fără un debugger și fără mesaj de eroare, este dificil să obțineți eroarea –  > Por Moataz Elmasry.
Tony Delroy
vector <vector <int> > G;

Acest lucru creează un vector de vectori de indici, dar inițial nu există elemente de vectori de indici. În ciuda acestui fapt, se apelează G.at(i)... care – pentru orice valoare a lui i, accesează imediat un element inexistent.

Separat, rand() returnează un număr întreg aleatoriu pe 32 de biți, deci va fi aproape întotdeauna mai mare decât 0,004 dvs. float. Este posibil să doriți să utilizați ceva de genul (rand() % 1000000 / 1000000.0). Subsistemul numerelor aleatoare ar trebui inițializat cu un apel ala srand(time(NULL));

În general, cel mai bine este să folosiți câteva numere std::cerr << "x is now " << x << '
';
– variabile de tipărire, dimensiuni ale vectorilor etc. – împrăștiat prin codul dvs. astfel încât să puteți vedea ce face și unde greșește. Alternativ, vedeți dacă puteți obține un depanator interactiv și treceți prin codul dvs. linie cu linie.

Comentarii

  • Am redimensionat M și G la 1000, dar asta nu mi-a rezolvat eroarea. Și eu m-am gândit la același lucru, dar 0,004 este probabilitatea pe care mi-a dat-o profesorul meu să o folosesc. Mi-a dat codul rand, spunând că rand() va alege un flotor aleator între 0 și 1. –  > Por Ashton Wiens.
  • Ar fi bine să vă găsiți un alt profesor: vedeți linux.die.net/man/3/rand. Redimensionarea s-ar putea să nu le fi rezolvat pe toate, dar ar fi trebuit să rezolve unele dintre ele – a mutat problema în codul ulterior cu o problemă similară. Dacă puneți o urmă de genul std::cerr << "gengraph returning
    ";
    veți putea să vedeți ce se tipărește ultima dată și să găsiți linia exactă care este încă cu probleme. –  > Por Tony Delroy.
StoryTeller – Unslander Monica

Înseamnă că ai indexat un vector în afara intervalului său.

vector::at() efectuează verificări ale intervalului. Deci, probabil că se datorează faptului că nu pre-alocați suficiente elemente pentru a G.

Slava

Prima eroare: în funcția gengraph() ați folosit un vector gol:

G.at(i) ...
G.at(j) ...

Da, apelați push_back, dar îl apelați din ceea ce a returnat metoda at(). Dar at() nu poate returna nimic indiferent de valoarea pe care o au i și j acolo, deoarece vectorul tău este gol. Una dintre soluții a fost introducerea acestei linii la începutul funcției gengraph()

G.resize( 1000 );

Al doilea sfat: evitați pe cât posibil să folosiți numere magice. Puneți ceva de genul:

const int size = 1000; 

La începutul fișierului dvs. și folosiți size în loc de numărul magic 1000. În special acest lucru:

int a = 1000;
float b = 0.004;
vector <vector <int> > G;
gengraph(a,b,G);
vector <int> M (1000); // use a here and better call it something more meaningfulness than a
int count = 0;
int i;
for (i = 0; i < a; i++) { // or use M.size() here or both
}

Tags:,