2015-11-01 4 views
1

t.PreorderTraversal(t, &t.getRoot()); Ошибка берет адрес временного объекта типа «Узел». Root - это объект класса Node. Функция PreoderTraversal будет обладать объектом как точкой, поэтому я указываю адрес объекта Node и возникшую ошибку. Разве это не правильный способ?Принимая адрес временного объекта типа 'Node'

class NodeList; 

class Node { 
private: 
    Node* parent; 
    int elem; 
    NodeList* children; 
    Node *next; 
    Node *prev; 

}; 

class NodeList { 
public: 
    NodeList(); 
    void addNodeAtRank(int, int); 
private: 
    Node* header; 
    Node* tailer; 
}; 

class Tree { 
private: 
    int n; 
    Node root; 
public: 
    Tree(); 
    void addNode(Tree &t, int, int, int); 
    void PreorderTraversal(const Tree& t, Node* p); 
    void PostorderTraversal(const Tree& t, Node* p); 
    void printXYofNode(const Tree& t, int nodeNumber); 
    Node getRoot(); 
    Node* getNodeByElem(Node& n, int); 
}; 

Node::Node() { 

    children = nullptr; 
    parent = nullptr; 
    elem = 0; 
    next = nullptr; 
    prev = nullptr; 

} 

NodeList::NodeList() { 

    header = new Node(); 
    tailer = new Node(); 

    header->next = tailer; 
    tailer->prev = header; 
} 

void NodeList::addNodeAtRank(int rank, int e) { 

    Node *v = new Node(); 
    v->elem = e; 

    int count = 1; 
    Node *NodeAtRank = header->next; 

    while (count != rank) { 
     NodeAtRank = NodeAtRank->next; 
     count++; 
    } 

    v->next = NodeAtRank; 
    v->prev = NodeAtRank->prev; 
    NodeAtRank->prev = v; 
    NodeAtRank->prev->next = v; 

} 

bool NodeList::empty() const { 
    return header->next == tailer; 
} 

Tree::Tree() { 

    n = 0; 
    //root = Node(); 
} 

void Tree::addNode(Tree& t, int NodeElement, int ParentNode, int SiblingOrder) { 

    //Node *treeNode = new Node(); 

    if (t.empty() && ParentNode == -1 && SiblingOrder == -1) { 
     t.root = Node(); 
     t.root.elem = NodeElement; 
     t.root.children = new NodeList(); 
    } else { 

     Node* nodeParent = t.getNodeByElem(t.root, ParentNode); 

     NodeList *childrenNodelist = nodeParent->children; 
     childrenNodelist->addNodeAtRank(SiblingOrder, NodeElement); 

     nodeParent->children = childrenNodelist; 
    } 

    n++; 
} 

Node* Tree::getNodeByElem(Node& root, int nodeElem) { 

    if (root.elem == nodeElem) 
     return &root; 
    else { 
     NodeList *rootChildren = root.children; 

     Node *head = rootChildren->header; 

     while (head->next != rootChildren->tailer) { 

      if (!head->next->isExternal()) 
       return getNodeByElem(*(head->next), nodeElem); 
      else { 
       if (head->next->elem == nodeElem) 
        return head->next; 

       head = head->next; 
      } 
     } 

     return new Node(); 
    } 
} 

void Tree::PreorderTraversal(const Tree& t, Node* p) { 

    cout << p->elem; 
    NodeList *mychildren = p->children; 
    Node *traversal = mychildren->header->next; 

    while (traversal != mychildren->tailer) { 
     cout << " "; 
     PreorderTraversal(t, traversal->next); 
     traversal = traversal->next; 
    } 

} 

void Tree::PostorderTraversal(const Tree& t, Node* p) { 

    NodeList *mychildren = p->children; 
    Node *traversal = mychildren->header->next; 

    while (traversal != mychildren->tailer) { 
     PreorderTraversal(t, traversal); 
     traversal = traversal->next; 
    } 
    cout << p->elem; 
} 

bool Tree::empty() const { 
    return n == 0; 
} 

int Tree::size() const { 
    return n; 
} 

Node Tree::getRoot() { 
    return root; 
} 

int main(int argc, const char * argv[]) { 

    char Type = NULL; 
    int nodeNumber = 0; 
    int nodeParent = 0; 
    int nodeOrderInSibling = 0; 

    Tree t = Tree(); 
    cin >> Type; 
    while (Type != 'Q') { 
     if (Type == 'I') { 
      cin >> nodeNumber >> nodeParent >> nodeOrderInSibling; 
      t.addNode(t, nodeNumber, nodeParent, nodeOrderInSibling); 
     } else if (Type == 'P') { 
      t.PreorderTraversal(t, &t.getRoot()); 
     } else if (Type == 'T') { 
      t.PostorderTraversal(t, &t.getRoot()); 
     } else if (Type == 'C') { 
      cin >> nodeNumber; 
      t.printXYofNode(t, nodeNumber); 
     } else { 
      cout << "Wrong input type!!!" << endl; 
     } 

     cin >> Type; 
    } 

    return 0; 
} 
+0

Рассмотрите возможность отступов кода немного лучше, его очень трудно прочитать прямо сейчас. –

+0

Пропущенные функции прототипа нечетны. Почему вы ссылаетесь на ссылки на объекты Tree в качестве аргумента? Это требует, чтобы вы указывали объект * дважды * во время вызовов. 't.PreorderTraversal (t, & t.getRoot()); t.PostorderTraversal (t, & t.getRoot()); ' « это »является неявным параметром в C++, поэтому я думаю, что было бы более целесообразно либо опустить параметр Tree (поскольку он не нужен), либо объявить функционирует как статический. – tweej

ответ

0

Ошибка компилятора в точности верна. Вы : с адресом временного (и это является нарушением стандарта). Tree :: getRoot() возвращает копию класса Node, поэтому & t.getRoot() является адресом временного. Я думаю, вы хотели бы вернуть указатель из getRoot(). Синтаксис для этого будет:

Node * getRoot(); 
1

Эта функция возвращает скопировать из Node объекта, который является членом Tree

Node getRoot(); 

Таким образом, в этой строке вы получаете адрес этого объекта который сразу же отбрасывается.

t.PreorderTraversal(t, &t.getRoot()); 

Указатель, который вы оставили, называется оборванным указателем, поскольку он не указывает на действительный объект.

Рассмотрим изменение getRoot как этот

Node* Tree::getRoot() { 
    return &root; 
} 

Вы, конечно, должны убедиться, что Root объект не выходит из сферы в то время как вы используете этот указатель

0

Изменение:

Node Tree::getRoot() { 
    return root; 
} 

:

Node& Tree::getRoot() { 
    return root; 
} 

в противном случае &t.getRoot() - возвращает адрес временного объекта, который является неопределенным поведением незаконным.

+0

+1 для привязки к ссылкам вместо указателей в этом случае, но -1, потому что это не неопределенное поведение. Это просто незаконно. – tweej

+0

@tweej исправлено, спасибо за указание, что вне – marcinj

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