2017-01-02 3 views
2

Я продолжаю получать ошибку сегментации в моем коде C++, который я отслеживал с помощью GDB через поток выполнения, и не вижу, откуда эта проблема. Моя программа создает объект Graph из списка объектов Vertex в основном классе AsTheCrowFlies. Фактическое создание объекта Graph происходит в makeGraph (const std :: vector). Линия в makeGraph, где начинается проблема, где я вызвать другую функцию checkEdges (Карта карта, Const Vertex & К, Const & С), которая выглядит следующим образом:Попытка разрешить ошибку сегментации

bool Graph::checkEdges(Map &map, const Vertex &To, const Vertex &From) { 

     if(map.find(To)!=map.end()) { 

     std::vector<Edge> edges = map[To]; 

     for (auto itr = edges.begin(); itr!=edges.end(); ++itr) { 

       if(itr->getDestination()==From) 
        return true; 

      } 

    } 

    return false; 

} 

Основываясь на том, как выход из GDB он выглядит когда, если оператор в течение цикла выполняется, и пытается использовать перегруженный == функции в классе Vertex:

 bool Vertex::operator == (const Vertex &other) const { 

     if (name==other.name && latitude==other.latitude && 
     longitude == other.longitude) { 

      return true; 

     } 

    return false; 

    } 

он выдает сообщение об ошибке: «не удается получить доступ к памяти по адресу 0x4a8>» The полный список сообщения об ошибках, когда я использую команду bt в GDB:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7b8f6f3 in std::string::size() const() 
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
(gdb) bt 
#0 0x00007ffff7b8f6f3 in std::string::size() const() 
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#1 0x000000000040a729 in std::operator==<char> (__lhs=" ", 
__rhs=<error reading variable: Cannot access memory at address 0x4a8>) 
at /usr/include/c++/4.8/bits/basic_string.h:2495 

#2 0x000000000041a30d in Vertex::operator== (this=0x671b58, other=...) 
at Vertex.cpp:50 

#3 0x0000000000415fb7 in Graph::checkEdges (this=0x7fffffffe880, 
map=std::unordered_map with 50 elements = {...}, To=..., From=...) 
at Graph.cpp:364 

#4 0x00000000004157cf in Graph::makeGraph (this=0x7fffffffe880, 
input=std::vector of length 50, capacity 50 = {...}) at Graph.cpp:161 

#5 0x0000000000414bea in Graph::setVertices (this=0x7fffffffe880, 
v=std::vector of length 50, capacity 64 = {...}) at Graph.cpp:38 

#6 0x0000000000402b62 in AsTheCrowFlies::menu (this=0x7fffffffe800, 
filename=0x7fffffffec48 "cap_cities.txt") at AsTheCrowFlies.cpp:17 

#7 0x000000000041a05c in main (argc=2, argv=0x7fffffffe9c8) at main.cpp:24 

Вот полная версия makeGraph (Const Vertex вход):

Map Graph::makeGraph(std::vector<Vertex> input) { 

    Map new_graph; 

    size_t size, n, mid,index; 

    size = input.size(); 

    n = size - 1; 

    mid = ((size + size%2)/2)-1; 

    if (size<1) 
return new_graph; 


double mean,max,min,median; //double variables for mean, median, maximum, minimum, sum of squares and standard deviation created 

    //vector used to hold the distances between adjacent vertices 
std::vector<double> dist(size); 


    for (int i = 0; i < size; i++) { 

     mean=0.0; //set average/mean to "0" 


     if(new_graph.find(input[i])==new_graph.end()) { //if the current Vertex has no map entry, add it here 

     std::vector<Edge> edges(size);    
     new_graph[input[i]] = edges;   

     } 

     //Create and sort duplicate list with each Vertex moved to 
     the front in turn   

     std:vector<Vertex> list(size); 

     list = input; 

     sort(list.begin(),list.end(),[&](const Vertex &v1, const Vertex &v2){return findMinDist(input[i].getLatitude(),input[i].getLongitude(),v1.getLatitude(),v1.getLongitude()) < findMinDist(input[i].getLatitude(),input[i].getLongitude(),v2.getLatitude(),v2.getLongitude()) ;}); 


     //Gets mean and fills distance tracking vector 


     for (int j = 0; j < size; j++) { 

     dist[j]=findMinDist(input[i].getLatitude(),input[i].getLongitude(),input[j].getLatitude(),input[j].getLongitude());  
     mean+=dist[j]/size;//accumulates mean value 

      }   


     min = dist[1]; 



     max = dist[n]; 


    if(size%2==0) { //calculates median distance value for... 

    median = (dist[mid]+dist[mid+1])/2; //...even sized vectors and... 

     } else {median = dist[mid];} //...odd sized vectors 


    if(mean >= median) { //index value is calucated for... 

    index = (mid+1)*(mean-min)/(max-min); //...case where mean is greater than or equal to median and... 


     } else {index = (mid+1)*(median-min)/(max-min);} //...case where mean is less than median and... 


    for (int k = 0; k < index; k++) { // 

     if(!checkEdges(new_graph,list[0],list[k])){ 

    new_graph[list[0]].push_back(Edge(list[0],list[k],dist[k])); 

     } 


     if(k!=0) { 

      if(new_graph.find(list[k])==new_graph.end()) {//SEGMENTATION 
                  //FAULT STARTS 
                  //HERE 

     std::vector<Edge> edges(size); 

        new_graph[list[k]]=edges; 

        new_graph[list[k]].push_back(Edge(list[k],list[0],dist[k])); 

      } else { 

     if(!checkEdges(new_graph,list[k],list[0])) { 

     new_graph[list[k]].push_back(Edge(list[k],list[0],dist[k]));  

        } 

       } 

     } 

     } 


    dist.clear(); 

    } 

return new_graph;  

}

И подпись getDestination является

Vertex& Edge::getDestination() {return destination;} 

Я смотрел на это и не видя, почему здесь произошла ошибка сегментации. Пожалуйста помоги! Я включил соответствующие разделы кода, где, похоже, происходит ошибка, но если вам нужен еще один код, чтобы понять, что происходит, сообщите мне.

+0

Вы проверили, действительно ли 'From'? если это «nullptr», это объяснит многое. –

+0

Вы пытались использовать правильный тип вместо автоматического? Auto иногда ведет себя странно – Kev1n91

+0

, и это может быть быстрее: 'std :: vector edge = map [To];' => 'const std :: vector & edge = map [To];' –

ответ

0

Скорее всего, getDestination() возвращает указатель на недействительный/недействительный объект или даже null.

В любом случае, я бы использовал отладчик. И я бы немного адаптировал код, чтобы легче было отлаживать и проверять объекты. Удачи!

 Vertex &edgeFrom = itr->getDestination(); 
     if(edgeFrom==From) 
      return true;