2016-07-07 4 views
1

Я пытаюсь пересечь общее дерево. Для этого примера у меня есть эта структура, которая поддерживает мои дочерние и родительские отношения.Обход общего дерева в C++

struct DataItem { 
    int id; 
    DataItem* root; 
    vector<DataItem*> children; 
}; 

По сравнению с бинарной обходе дерева, я не используя * левый и правый *, так как там может быть более чем один узел. Чтобы пройти код, я использую эти два метода, называемые constructMap, а затем traverseTree.

void traverseTree(std::vector<int>::iterator current, std::vector<int>::iterator end, 
    std::vector<int>::iterator next, DataItem *root) { 
    while (current != end) { 
     DataItem *childNode; 
     childNode->id = *current; 
     childNode->root = root; 
     if (*current + 1 == *next) { 
      root->children.push_back(childNode); 
     } else { 
      // traverse the next tree 
      traverseTree(++current, end, ++next, childNode); 
     } 
     ++next; 
     ++current; 
    } 
} 


void constructMap(std::vector<int>::iterator start, std::vector<int>::iterator end) { 
    auto next = std::next(start, 1); 
    DataItem *parentNode; 
    parentNode->id = *start; 
    parentNode->root = NULL; 
    traverseTree(++start, end, ++next, parentNode); 
    cout << " at the end " << endl; 
} 

Я до сих пор, чтобы проверить логику, чтобы увидеть обход действительно функционирует, хотя я полагаю, его нет, но я получаю следующее сообщение об ошибке:

Segmentation fault (core dumped) 

После некоторых закомментировать, получается что это происходит в constructMap, когда я вызываю этот вызов:

parentNode->id = *start; 

Если я что-то вроде этого: вместо

int val = *start; 
parentNode->id = val; 

Я могу передать эту ошибку сегментации и продолжить движение вперед.

Я передаю итератор вектора к моей карте в процессе, содержащий что-то вроде этого: 1,3,4,5,7,8,10

constructMap(allNumbers.begin(), allNumbers.end()); 
+0

* После некоторых комментариев *, - Итак, вы не используете отладчик? – PaulMcKenzie

ответ

3

Вопрос заключается в том, что вы пытаясь получить доступ к неинициализированному указателю parentNode. Возможно, это простой объект:

DataItem parentNode; 
parentNode.id = *start; 
parentNode.root = NULL; 
traverseTree(++start, end, ++next, &parentNode); 
+0

tsandy правильный, думаю. Я немного обеспокоен тем, что начало используется с std :: next, и значение получается непосредственно из него после факта. Дело в том, что я не помню, чтобы сперва, если std :: next продвигается вперед или нет. – Andrew

+0

@ Когда я посмотрел документацию на std :: next, все, что было упомянуто, заключается в том, что исходный указатель на итератор копируется и увеличивается, в отличие от доступа и приращения – angryip

+0

@ Если он будет продвигать указатель, он будет эквивалентны оператору ++() и, следовательно, избыточным. На самом деле я не знаю никакой стандартной библиотечной функции, которая принимает аргумент итератора неконстантной ссылкой и мутирует ее. –