Получение адреса временного объекта типа «Узел»

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;
}

1

Решение

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

Node getRoot();

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

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

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

Рассмотреть вопрос об изменении getRoot как это

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

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

1

Другие решения

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

Node * getRoot();
0

Изменить:

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

чтобы:

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

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

0
По вопросам рекламы [email protected]