2015-03-05 3 views
-2

Я довольно новичок в языке C++, и я пытаюсь написать рекурсивный метод для перемещения по дереву. У меня есть метод перемещения, но есть одна строка кода, которая вызывает ошибку сегментации. Я проверил это, комментируя и раскомментируя строку, компилируя и выполняя. Я исследовал причину возникновения ошибок сегментации и не понимаю, почему любое из того, что я делаю, вызывает проблему с памятью. Может ли кто-нибудь дать мне совет о том, что я делаю неправильно?Ошибка сегментации C++

map<int, Node> theNodes; 

void initialize() 
{ 
    // first we read the data 
    while (inStream.hasNext()) 
{ 
    string nextLine = inStream.nextLine(); 
    Node newNode = Node(nextLine); 
    this->theNodes[newNode.getSequence()] = newNode; 
} 
} 

Код для getDownLinks() и getSequence

vector<int> downLinks; 
int sequence; 

vector<int> Node::getDownLinks() const 
{ 
    return this->downLinks; // 
} 

int Node::getSequence() const 
{ 
    return this->sequence; 
} 

Прослеживание Код класса

int totalPayoff; 
Node headNode; 

int Traversal::traverse() 
{ 

    Node headNode = theNodes[0]; 
std::vector<int> downLinks = headNode.getDownLinks(); 
for(int i = 0; i < downLinks.size(); i++) 
{ 
    int a = 0; 
    Node currentNode = theNodes[downLinks[i]]; 
    traverseInner(a, currentNode); 
} 
return this->totalPayoff; 
} 

Вот функция traverseInner

int Traversal::traverseInner(int& level, Node& node) 
{ 

std::vector<int> nodeDownLinks = node.getDownLinks(); 

if(nodeDownLinks.size() == 0) 
{ 
    totalPayoff = totalPayoff + node.getPayoff(); 
    return 0; 
} 

    for(int i = 0; i < nodeDownLinks.size(); i++) 
    { 
     int a = 0; 
     Node currentNode = theNodes[nodeDownLinks[i]]; <-- This causes segmentation error. 
     traverseInner(a, currentNode); 
    } 


return totalPayoff; 
} 

Любые переменные, которые не объявлены здесь, объявляются в файле заголовка. Код компилируется отлично.

Я также хотел бы упомянуть, что я написал этот код по-разному, и благодаря моим наблюдениям пришел к выводу, что к любой переменной, которая пытается получить доступ к фигурным скобкам вложенного оператора, нельзя получить доступ память. Даже int a переменная, которая объявлена ​​прямо над оператором проблемы и даже жестко закодированные данные, которые должны быть там, такие как nodeDownLinks. Если я попытаюсь распечатать через стандартный вывод размер вектора внутри одного из вложенных операторов, я также получу ошибку сегментации.

+0

'getDownLinks()' если это возвращает член, а не локальную переменную, вы можете вернуть его по ссылке const и сохранить результат как 'const std :: vector & downLinks', если вам не нужно изменять Это. Это спасет копирование вектора. –

+0

Вы пытались запустить его через GDB? Можете ли вы опубликовать код 'node.getDownLinks()'? –

+1

Где инициализируется или заполняется 'theNodes'? Очевидно, вы пытаетесь получить доступ к индексу вне пределов. – Falmarri

ответ

1

Возможно, значение внутри «nodeDownLinks [i]» не инициализировано, имея случайное значение памяти, тогда вы пытаетесь получить доступ к этой позиции в массиве «theNodes» 10 и дает вам ошибку сегментации.

Пожалуйста, убедитесь, что значения внутри «nodeDownLinks» инициализированы.

+0

Значение внутри ** nodeDownLinks ** является целым числом. Возможно ли, что это проблема? – superuserdo

+0

Да, обязательно всегда имея значения, инициализированные, например, до нуля – Drewen

+0

Я просто проверил ваш совет. Я распечатал размер nodeDownLinks (который был 3) вне цикла for. Затем в цикле for я распечатал nodeDownLinks [i] и снова произошла ошибка сегментации. Я прокомментировал весь другой код в цикле for. Является ли цикл for проблемой? Это кажется. – superuserdo

0

99% сбой, потому что theNodes имеет меньше размера, затем nodeDownLinks[i] содержит индекс. Так nodeDownLinks [я] содержит неправильный индекс, u'd лучше проверить его и печатать то, что идет не так, это так:

int a = 0; 
    int link = nodeDownLinks[i]; 
    if (theNodes.size() <= link) 
     std::err << "Wrong link " << link << " in Node" << std::endl; 
    else 
     traverseInner(a, theNodes[link]); 

Он не должен врезаться, и вы можете найти неверный индекс в nodeDownLink легко!

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