使用和不使用新指针的区别

Difference between using and not using new pointer

请参考此处给出的代码:

此代码是 C++ 中堆栈实现的一部分:

代码 1:

void Stack::pop()
{
    if (top != 0) {
        node* temp = top;
        top = top -> link;
        delete temp;
    }
}

代码 2:

void Stack::pop()
{
    if (top != 0) {
        node* temp = new node;
        temp = top;
        top = top -> link;
        delete temp;
    }
}

在第一个示例中,我没有使用 new,而在第二个示例中我确实使用了它。在 运行 上,两者都给出了完整程序的相同输出,可以在下面找到:

#include <iostream>

using namespace std;

struct node {
    string name;
    node* link;
};

class Stack
{
    node* top;
public:
    Stack();
    void push(string s);
    void pop();
    void display();
    ~Stack(){}
};

Stack::Stack() {
    top = 0;
}

void Stack::push(string s)
{
    node* temp = new node;
    temp -> name = s;
    temp -> link = top;
    top = temp;
}

void Stack::pop() // Function in question
{
    if (top != 0) {
        node* temp = new node;
        temp = top;
        top = top -> link;
        delete temp;
    }
}

void Stack::display()
{
    node* temp = new node;
    temp = top;
    while (temp != 0)
    {
        cout << temp -> name << "\n";
        temp = temp -> link;
    }
}

int main() {
    Stack s;
    s.push("Ra");
    s.push("Sa");
    s.push("Ga");
    s.pop();
    s.display();
}

这里使用和不使用 new 指针有什么区别

另外,内存是自动释放还是我必须在析构函数中释放?如果可以,怎么做?

第二个代码片段中存在内存泄漏,尽管它看起来运行良好。 new nodenode* temp = new node;没有意义,因为temp一下子赋给了top。那么new node创建的原内存地址就丢失了,不能再deleted了。

Also does the memory automatically free itself or do I have to do it in destructor?

每个对象 newed 都必须由您自己 deleted。考虑一下smart pointers,他们会为你处理这些事情。

在这些行中:

    node* temp = new node;
    temp = top;

您分配新节点,将其存储在 temp 变量中,然后将下一个变量存储在同一变量中的另一个指针中。这样新节点就会丢失并使用更新的节点。 node* temp = new node; 除了泄漏内存外没有任何影响。

Also does the memory automatically free itself or do I have to do it in destructor?

没有。内存不会自动释放。而且您几乎从未真正手动调用对象析构函数。

If so, how to do it?

老方法是使用delete。但是在现代 C++ 中,你不应该使用裸指针,真的应该考虑使用 std::unique_ptr.

在使用 new/allocating 内存时,您造成了内存泄漏。

node* temp = new node;
temp = top; //temp is now pointing to a new memory location.
            //Thus the memory allocated by in the previous code line gets leaked

Code1 是正确的方法。代码 2 导致内存泄漏。

您必须在析构函数中使用删除运算符删除分配的内存。

Stack::~Stack()
{
    while(NULL != top)
    {
        node* temp = top;
        top = top->link;
        delete temp;
    }
}

智能指针解决方案。您将需要 c++11 编译器将以下代码编译为 compile/work.

#include <iostream>
#include <memory>

using namespace std;

struct node {
    string name;
    std::unique_ptr<node> link;
};    
typedef std::unique_ptr<node> node_ptr;

class Stack
{
    node_ptr top;
public:
    Stack();
    void push(string s);
    void pop();
    void display();
    ~Stack(){}
};

Stack::Stack() {
}

void Stack::push(string s)
{
    auto temp = std::make_unique<node>();
    temp -> name = s;
    temp -> link = top;
    top = temp;
}

void Stack::pop()
{
    if (top != null) {
        top = top -> link;
    }
}

void Stack::display() const
{
    node* temp = top.get();
    while (temp != 0)
    {
        cout << temp -> name << "\n";
        temp = (temp -> link).get();
    }
}

int main() {
    Stack s;
    s.push("Ra");
    s.push("Sa");
    s.push("Ga");
    s.pop();
    s.display();
}