2013-04-14 2 views
2

У меня есть следующий Vertex-структура в Graph классе:C++ «Нарушение прав доступа чтение место» Ошибка

struct Vertex 
{ 
    string country; 
    string city; 
    double lon; 
    double lat; 
    vector<edge> *adj; 

    Vertex(string country, string city, double lon, double lat) 
    { 
     this->country = country; 
     this->city = city; 
     this->lon = lon; 
     this->lat = lat; 
     this->adj = new vector<edge>(); 
    } 
}; 

При вызове метода я написал под названием getCost(), я получаю то же необработанное исключение

нарушение прав доступа чтения местоположение 0x00000048

, и я не могу понять, почему.

getCost() метод:

void Graph::getCost(string from, string to) 
{ 

    Vertex *f = (findvertex(from)); 
    vector<edge> *v = f->adj;  // Here is where it gives the error 
    vector<edge>::iterator itr = v->begin(); 

    for (; itr != v->end(); itr++) 
    { 
     if (((*itr).dest)->city == to) 
      cout << "\nCost:-" << (*itr).cost; 
    } 
} 

Метод findvertex() возвращает значение типа Vertex*. Почему я продолжаю получать эту ошибку?

метод findVertex:

Vertex* Graph::findvertex(string s) 
{ 
    vmap::iterator itr = map1.begin(); 
    while (itr != map1.end()) 
    { 
     if (itr->first == s){ 

      return itr->second; 
     } 
     itr++; 
    } 
    return NULL; 
} 

Где map1 определяется:

typedef map< string, Vertex *, less<string> > vmap; 
vmap map1; 
+1

Вы отправили все рядом с наиболее подходящей частью. Подсказка: findvertex – SomeWittyUsername

+0

Можете ли вы разместить findVertex, пожалуйста? – Alan

+0

Что такое findvertex? то есть, если он не возвращает конкретный объект Вершины, то это ваша ошибка. – Chris

ответ

7

Вы еще не опубликовали метод findvertex, но доступ для чтения Нарушений со смещением, как 0x00000048 означает, что Vertex* f; в функции getCost получает нуль, а при попытке получить доступ к элементу adj в указателе null Vertex (т.е. , в f), это смещение к adj (в этом случае, 72 байт (0x48 байт в десятичной системе)), то чтение рядом с адресом 0 или null памяти.

Ведение чтения, как это нарушает защищенную память операционной системы, и что более важно, означает то, что вы направляете на это не является допустимым указателем. Убедитесь, что findvertex не возвращается нуля, или сделать comparisong для нуля на f, прежде чем использовать его, чтобы держать себя в здравом уме (или использовать Assert):

assert(f != null); // A good sanity check

EDIT:

Если вы есть map для делать что-то, как найти, вы можете просто использовать find метода карты, чтобы убедиться, что вершина существует:

Vertex* Graph::findvertex(string s) 
{ 
    vmap::iterator itr = map1.find(s); 
    if (itr == map1.end()) 
    { 
     return NULL; 
    } 
    return itr->second; 
} 

Просто убедитесь, что вы все еще осторожны, чтобы обрабатывать случай ошибки, где он возвращает NULL. В противном случае вы будете нарушать это нарушение.

+0

Я заменил метод findvertex соответствующим образом, однако ошибка все тот же –

+0

@AlexAlex Это означает, что даже если это что-то находит, у вас могут быть две потенциальные проблемы. Во-первых, вы фактически вставляете нуль в карту для этого конкретного строкового ключа. Другая заключается в том, что вершина фактически не находится на карте в первую очередь. Контрольная точка отладки (для IDE) или выполнение печати ключа/значения и выполнение печати при добавлении значений на карту, чтобы убедиться, что вы не добавляете нуль, было бы целесообразно. – 2013-04-14 02:35:48

+0

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

2
Vertex *f=(findvertex(from)); 
if(!f) { 
    cerr << "vertex not found" << endl; 
    exit(1) // or return; 
} 

Поскольку findVertex может вернуться NULL, если он не может найти вершину.

В противном случае это f->adj; пытается сделать

NULL->adj; 

, который вызывает нарушение доступа.

+0

, который действительно поймает ошибку. Однако вы видите, почему метод findvertex возвращает NULL, если значение действительно находится в map1? Я вызвал метод findvertex в другом месте и распечатал атрибут возвращаемой вершины просто отлично. –

+0

@AlexAlex Нет ничего плохого в вашем коде. Проблема заключается не в алгоритме поиска. Я думаю, что это вставка в карту. Если вы можете использовать некоторый отладчик и поместить точку останова в алгоритме find, чтобы увидеть, что содержит карту1, когда она достигает, вы можете решить это примерно через 10 минут. :) – 2013-04-14 02:30:22

Смежные вопросы