2017-07-19 12 views
1

Ich überprüfe meinen Code für Speicherverluste mit Valgrind unter Linux. Das Programm läuft für die erste Stunde gut, gibt aber den folgenden Fehler für eine bestimmte Kombination von gerichteten Kanten zurück. Ich frage mich, ob ich vor der Ausführung von dijkstra_sp.cpp nach NULL suchen muss. Ich habe im folgenden Code Zeilen identifiziert, die im Mittelpunkt dieses Problems stehen könnten.Valgrind Lecksuche meldet Fehler segfault

==25051== Process terminating with default action of signal 11 (SIGSEGV) 
==25051== Access not within mapped region at address 0x0 
==25051== at 0x410D79: List<DirectedEdge*>::addToList(DirectedEdge*, List<DirectedEdge*>*) (linked_list.h:76) 
==25051== by 0x410AD5: pathTo(DijkstraSPTree*, ShortestPath*, int) (dijkstra_sp.cpp:77) 
==25051== by 0x423C54: getShortestPath(EdgeWeightedDigraph*, int, int) (vehicle_searching.cpp:45) 
==25051== by 0x4187E5: netPathWeight(EdgeWeightedDigraph*, int, int, int) (vehicle_Linux.cpp:1099) 
==25051== by 0x41B8E0: Schedule(int, int, VehicleState*) (vehicle_Linux.cpp:781) 
==25051== by 0x415719: updateAndRender(VehicleState*, int) (vehicle_Linux.cpp:237) 

dijkstra_sp.cpp

struct DirectedEdge { 
    int32 from; 
    int32 to; 
    real32 weight; 
}; 

void 
pathTo(DijkstraSPTree *spTree, ShortestPath *shortestPath, int32 dest) 
{ 
    // should I assert input not null? <<<<<<<<<<<<<<<<<<<<<<<<<<< 
    List<DirectedEdge *>::traverseList(freeDirectedEdge, shortestPath->edgeList); 
    List<DirectedEdge *>::emptyList(&shortestPath->edgeList); 
    shortestPath->totalWeight = spTree->distTo[dest]; 

    // check if there IS a path to dest from the root of spTree 
    if (spTree->distTo[dest] < INFINITY) { 
     DirectedEdge *nextEdge = spTree->edgeTo[dest]; 
     if(nextEdge != 0) 
     nextEdge = spTree->edgeTo[nextEdge->from]; 
    for (DirectedEdge *nextEdge = spTree->edgeTo[dest]; 
     nextEdge != 0; 
     nextEdge = spTree->edgeTo[nextEdge->from]) { 
// FOLLOWING IS LINE 77 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
     shortestPath->edgeList = 
     List<DirectedEdge *>::addToList(nextEdge, shortestPath->edgeList); 
    } 
    } 

linked_list.h

// item T to the list 
template<typename T> List<T> * 
List<T>::addToList(T newItem, List<T> *list) 
{ 
// Could sizeof(List<T>) being zero cause this issue? <<<<<<<<<<<<<<<<<<< 

    List<T> *resultList = (List<T> *)malloc(sizeof(List<T>)); 
FOLLOWING IS LINE 76 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    resultList->item = newItem; 
    resultList->next = list; 
    return resultList; 
} 
+0

Nur weil Ihr Programm an einem bestimmten Ort abgestürzt ist, heißt das nicht, dass es sich um den Fehler handelt. Dein Fehler kann überall sein. Zum Beispiel, wenn 'List ' ein POD ist, ist das Zuweisen von 'malloc()', wie der gezeigte Code tut, undefiniertes Verhalten und ein garantierter Fehler. –

Antwort

0

Sie haben über genügend Arbeitsspeicher ausgeführt. Der Aufruf an malloc gibt NULL (0) zurück, wenn das geschieht. Wenn Sie versuchen, in diesen ungültigen Zeiger zu schreiben, erhalten Sie den Absturz.

+0

Ich habe das vermutet, also werde ich diesem Programm mehr Speicher zuweisen und sehen, ob es abstürzt. Es funktioniert gut ohne Valgrind für kleinere Netzwerk von Kanten und Ecken. – Far

+0

@Far Für jedes ernsthafte Programm sollten Sie den Rückgabewert von 'malloc' für' NULL' überprüfen und elegant mit einem Fehler beenden. Viele einfache Apps definieren einfach ein 'safe_malloc', das dies tut und rufen dieses anstelle von' malloc' auf. Mit C++ sollte man sowieso 'new' verwenden. Es wird eine Ausnahme ausgelöst, wenn der Arbeitsspeicher nicht ausreicht. – Gene

+0

@Gene oh ja, ich weiß nicht warum ich vergessen habe nach 'NULL' zu suchen und' exit (EXIT_FAILURE) 'zu benutzen – Far