Avatar billede corona10 Nybegynder
10. april 2005 - 21:03 Der er 8 kommentarer

iterator trouble

Hej, jeg har f'lgende der returnerer en iterator over Edge*

EdgeList::const_iterator Graph::incidentEdges(Vertex* v) {
  EdgeList::const_iterator edg = v->getIncoming()->begin();
  EdgeList::const_iterator edg2 = v->getOutgoing()->begin();
  EdgeList* result = new EdgeList();
  while(v->getIncoming()->begin() != v->getIncoming()->end()) {
    result->push_back(*edg);
    ++edg;
  }
  while(v->getOutgoing()->begin() != v->getOutgoing()->end() ) {
    result->push_back(*edg2);
    ++edg2;
  }
  EdgeList::const_iterator incident = result->begin();
  return incident;
}

N[r jeg s[ vil bruge denne iterator som i f'lgende:
Graph* g = new Graph("G");
Vertex* v = g->insertVertex("v");

EdgeList::const_iterator iter3 = g->incidentEdges(v);
  while(*iter3) {
    std::cout << "incident edge " << (*iter3)->getName() << std::endl;
    ++iter3;
  }
giver den segmentation fault. Jeg regner med at det er fordi iteratoren kan v;re tom, men hvordan tester jeg for dette?
Avatar billede bertelbrander Novice
10. april 2005 - 23:40 #1
En iterator kan ikke være tom.
Normalt bruger tester man på om iteratoren er det samme som kontainerens end() (eller begin() hvis det er en reverse iterator).

Jeg forstår ikke denne:
while(v->getOutgoing()->begin() != v->getOutgoing()->end() )

Så vidt jeg kan se vil den forstætte uendeligt.
Avatar billede corona10 Nybegynder
11. april 2005 - 00:29 #2
ok fair nok
hvis vi så i stedet siger

while(*edg) { ... }

så får jeg stadig fejlen når jeg bruger iter3
Avatar billede bertelbrander Novice
11. april 2005 - 00:50 #3
Hvis result i Graph::incidentEdges() er tom, returneres result->begin(), denne vil så være det samme som result->end(), der ikke er en gyldig værdi.

Du er nødt til at lave en metode så brugeren af Graph::incidentEdges kan se om det den får er valid.

Du kunne lade Graph::incidentEdges returnere en pointer, der så kan være NULL
Avatar billede corona10 Nybegynder
11. april 2005 - 01:19 #4
yes, der er bare det ved det at brugeren af Graph::incidentEdges forventer en iterator over Edge*
jeg ved ikke om du har et forslag til hvordan jeg kan lave min løkke om, dvs de sidste 4 linier kode???
Avatar billede bertelbrander Novice
11. april 2005 - 01:27 #5
Du kunne give adgang til end():
  EdgeList::const_iterator iter3 = g->incidentEdges(v);
  while(iter3 != something->end())
  {
    std::cout << "incident edge " << (*iter3)->getName() << std::endl;
    ++iter3;
  }
Det er ikke kønt.

Hvis du er sikker på at der altid er mindst 1 element i listen (dvs den iterator der returneres fra g->incidentEdges(v) er valid, ie != something->end()) Kunne du sætte et mærke i det sidste element, det er heller ikke kønt.
Avatar billede bertelbrander Novice
11. april 2005 - 01:54 #6
I Graph::incidentEdges laver du en EdgeList (EdgeList* result = new EdgeList(); ) denne bliver ikke nedlagt igen (delete), det medfører et memory leak.
Du kunne lade funktionen returnere denne.
Avatar billede corona10 Nybegynder
17. april 2005 - 01:21 #7
ok, den kan s[ ikke lide n[r jeg laver ++iter p[ en iterator der ikke indeholder noget, alts[ hvis der ikke er nogen incidente kanter... hvordan tester jeg for dette?

ellers er der point for indsatsen hvis du laver et svar
Avatar billede bertelbrander Novice
17. april 2005 - 23:51 #8
En iterator alene kan ikke vide at den er kommet til enden, eller om den ikke "peger" på noget.

Man er nød til at have adgang til containerens end().
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester