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

时间:2016-10-19 06:37:41

标签: c++ pointers stack new-operator

请参阅此处给出的代码:

此代码是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();
}

在此处使用指针时差异是什么?

内存是否会自动释放,或者我必须在析构函数中执行此操作?如果是的话,该怎么做?

3 个答案:

答案 0 :(得分:5)

第二个代码段中存在内存泄漏,即使它看起来运行良好。 new nodenode* temp = new node;毫无意义,因为temp会立即分配给top。然后,new node创建的原始内存地址将丢失,并且无法再次delete

  

内存是否会自动释放,或者我必须在析构函数中执行此操作?

每个对象new ed必须由delete d自己完成。考虑一下smart pointers,他们会为你管理这些事情。

答案 1 :(得分:3)

在这些方面:

    node* temp = new node;
    temp = top;

您分配新节点,将其存储在temp变量中并将下一个变量存储在同一变量中另一个指针。这样新节点就会丢失并且更新。除了泄漏记忆外,node* temp = new node;没有任何效果。

  

内存也自动释放,或者我必须这样做   在析构函数?

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

  

如果是的话,怎么做?

旧方法是使用delete。但是现代的C ++你不应该使用赤裸裸的拥有指针,而且应该考虑使用std::unique_ptr

答案 2 :(得分:2)

使用new /分配内存时,会导致内存泄漏。

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导致内存泄漏。

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

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

智能指针解决方案。您将需要c ++ 11编译器来编译/工作以下代码。

#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();
}