我试图用c ++制作堆栈,但似乎遇到了问题。
#include "stdafx.h"
#include <iostream>
using namespace std;
class Node {
public:
int node_value;
Node * previous_node;
};
class Stack {
public:
Node * node_pointer;
int size = 0;
void push(int number) {
Node NewNode;
NewNode.node_value = number;
cout << number << endl;
if (size == 0) {
node_pointer = &NewNode;
cout << node_pointer << endl;
size += 1;
cout << "Pushed" << endl;
}
else if (size > 0)
{
NewNode.previous_node = node_pointer;
node_pointer = &NewNode;
cout << "Pushed" << endl;
size += 1;
}
}
void pop() {
if (size > 1) {
Node Temp_Node = *node_pointer;
cout << Temp_Node.node_value << endl;
node_pointer = Temp_Node.previous_node;
size -= 1;
}
else if (size == 1){
size -= 1;
Node Temp = *node_pointer;
cout << Temp.node_value;
}
else {
cout << "empty" << endl;
}
}
};
int main()
{
Stack stack;
Node a;
Node b;
Node * p1;
int num = 5;
a.node_value = num;
p1 = &a;
b = *p1;
cout << b.node_value << endl;
stack.push(10);
stack.pop();
system("PAUSE");
return 0;
}
它不返回节点值,而是返回一个地址。我有点困惑,因为当我用节点做同样的事情时,它工作得很好。在堆栈中,我将地址复制到指针node_pointer中,当我通过derefencing指针创建一个新节点时,它会回吐完全不同的实例变量。
答案 0 :(得分:4)
一个主要的问题是这两行:
Node NewNode;
...
node_pointer = &NewNode;
第一行定义 本地 变量。然后保存指向该局部变量的指针。并且该变量将超出范围,并且在函数结束时将破坏对象NewNode
。给你一个无效的指针。
取消引用该无效指针将导致undefined behavior。
标准解决方案是使用new
动态分配节点:
Node* NewNode = new Node;
...
node_pointer = NewNode;
当然,一旦你完成了节点,就必须记住delete
节点。
答案 1 :(得分:1)
问题来自函数push(),'newNode'是堆栈上的一个变量,编译器会在函数末尾自动调用它的析构函数。
为了避免这种情况,你应该使用'new'运算符在堆上创建'newNode',函数pop()有责任释放内存(使用'delete'运算符)。
如果'new'和'delete'操作符让您感到困惑,则可以使用'std :: shared_ptr'代替。
void push(int number) {
Node *NewNode = new Node{};
NewNode->node_value = number;
if (size == 0) {
node_pointer = NewNode;
cout << node_pointer << endl;
size++;
cout << "Pushed" << endl;
}
else if (size > 0)
{
NewNode->previous_node = node_pointer;
node_pointer = NewNode;
size++;
cout << "Pushed" << endl;
}
}
void pop() {
if (size > 1) {
Node* Temp_Node = node_pointer;
cout << Temp_Node->node_value << endl;
delete node_pointer;
node_pointer = Temp_Node->previous_node;
size--;
}
else if (size == 1) {
Node* Temp = node_pointer;
cout << Temp->node_value << endl;
delete node_pointer;
node_pointer = nullptr;
size--;
}
else {
cout << "empty" << endl;
}
}
此外,您可以利用SmartPointer:您对堆上的“新”和“删除”对象不负任何责任。
#include <memory>
using namespace std;
class Node {
using node_ptr = std::shared_ptr<Node>;
public:
int node_value;
node_ptr previous_node;
};
class Stack {
using node_ptr = std::shared_ptr<Node>;
public:
node_ptr node_pointer = nullptr;
int size = 0;
void push(int number) {
node_ptr NewNode = std::make_shared<Node>();
NewNode->node_value = number;
if (size == 0) {
node_pointer = NewNode;
cout << node_pointer << endl;
size++;
cout << "Pushed" << endl;
}
else if (size > 0)
{
NewNode->previous_node = node_pointer;
node_pointer = NewNode;
size++;
cout << "Pushed" << endl;
}
}
void pop() {
if (size > 1) {
node_ptr Temp_Node = node_pointer;
cout << Temp_Node->node_value << endl;
//delete node_pointer;
//no need to delete here, it will be automatically destructed when Temp_Node leaves this scope.
node_pointer = Temp_Node->previous_node;
size--;
}
else if (size == 1) {
node_ptr Temp = node_pointer;
cout << Temp->node_value << endl;
//delete node_pointer;
node_pointer = nullptr;
size--;
}
else {
cout << "empty" << endl;
}
}
};