Valgrind泄漏检测返回段错误

问题描述:

我正在Linux上使用Valgrind检查我的内存泄漏代码。该程序在第一个小时内运行良好,但对于有向边的某些组合返回以下错误。我想知道是否需要在执行dijkstra_sp.cpp之前检查NULL。我在下面的代码中找到了可能是此问题中心的行。Valgrind泄漏检测返回段错误

==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

仅仅因为你的程序在一个特定的地方崩溃了,这并不意味着这就是错误所在。你的bug可以在任何地方。例如,除非'List '是一个POD,如图所示,使用'malloc()'分配它是未定义的行为,并且是一个有保证的错误。 –

你已经用完了内存。 malloc的调用发生时返回NULL(0)。当您尝试写入该无效指针时,您会遇到崩溃。

+0

我怀疑这个,所以我要给这个程序分配更多的内存,看看它是否崩溃。如果没有Valgrind,对于较小的边和顶点网络,它工作正常。 – Far

+0

@Far对于任何严肃的程序,你应该检查'NULL'的'malloc'的返回值并且正常退出并报错。很多简单的应用程序只是定义了一个'safe_malloc'来完成这个操作,并调用它来代替'malloc'。无论如何,使用C++你应该使用'new'。当你内存不足时它会抛出异常。 – Gene

+0

@Gene哦是的,我不知道为什么我忘了检查'NULL'并使用'exit(EXIT_FAILURE)' – Far