在创建链表时使用new运算符

时间:2011-08-29 17:18:28

标签: c++ list visual-c++ linked-list new-operator

在以下程序中:

// illustration of linked list
#include <iostream>

using namespace std;

struct node {
    int data;
    struct node* next;
};

struct node* buildList();

int main() {

struct node* head = buildList();
cout << head->data;
}

struct node* buildList() {
    struct node* head = NULL;
    struct node* second = NULL;
    struct node* third = NULL;

    head = new node;      // builds up a pointer structure on heap
    second = new node;
    third = new node;

    head->data = 1;
    head->next = second;

    head->data = 2;
    second->next = third;

    head->data = 3;
    third->next = NULL;

    return head;
}

我不知道new运营商在这里的工作。他们执行什么任务? (我读到它在堆上分配空间。但我不知道它是什么意思)如果我删除这些语句没有输出,程序崩溃。那是为什么?

4 个答案:

答案 0 :(得分:3)

头部,第二个和第三个变量是指向内存中节点的指针。但是,在使用它们之前,它们必须指向内存中的有效节点。这是新运算符的用武之地。堆只是一个已分配给程序的内存区域,用于动态创建对象(而不是堆栈。请参阅here了解差异)。

答案 1 :(得分:3)

*编辑*

我以为我会在回答之前添加:

简单来说,堆栈是程序当前工作的地方,并且有点暂时。我的意思是你的main()函数可以调用另一个函数。该函数将有自己的范围({})之间的区域,它自己的局部变量,空间等。它可以反过来调用另一个函数。这些功能一直被“放在堆栈上”。一旦函数返回,它将从堆栈中取出,您将返回到启动的下一级别函数中的点。就好像你把一张纸放在你当前的笔记本上,记下一些笔记,然后把它取下来回到原来的页面。 “堆栈变量”是您在函数中以正常方式创建的,并且在离开范围时会死亡/破坏。

堆变量是静态/全局变量,或者是使用“new,malloc等”创建的变量。这些变量是永久性的,并且会持续存在/存在,直到您明确地对它们调用delete。它们将在创建它们的范围之外生存,如果你不跟踪它们,它们的资源将是不可释放的,你将有内存/资源泄漏。

正常发布

行:

struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;

都是在节点声明它是指向节点的指针之后创建指针。这些指针初始化为NULL或0.指针只是一个内存地址/位置,它还没有节点对象。所以,

node* ptr = NULL;  //creates pointer to a node object, but no node itself.
node  obj;         //creates an actual node object on the stack.

指针可以用来指向基于堆栈的对象,方法是将其地址与&amp;像这样的运算符:

node obj;  //Real object.
node* ptr = &obj;  //ptr points to the "address of" obj.

在您的情况下,在使用“new”创建节点指针之前,节点指针不会指向任何内容。之后,指针指向“动态分配”的内存,该内存将一直存在,直到你在其上调用“delete”。这样做的好处是内存可以在创建它的函数之外持久存在。所以:

void myFunction()
{
    node obj;
}  //obj dies here.

void myOtherFunction()
{
    node* ptr = new obj;
} //the "node" created by new will survive after this.

我可以继续,但你需要阅读一本c ++书并理解这一点 - 指针是你需要完全学习的语言的一个关键方面。

答案 2 :(得分:0)

struct node* head = NULL; - &gt;创建一个指针(由于赋值而指向null)

head = new node; - &gt;将内存分配给一个节点的大小,并指向该内存的开头

所以如果你的指针是NULL并且你永远不会告诉它指向一个节点(或任何东西)那么对那个指针或那个指针的任何操作都将失败

答案 3 :(得分:0)

new构造该类型的新对象。

在这种情况下,您正在构建一个新节点。但是在某些代码中,您不需要这样做,而只需使用对象即可。节点头; head.data = 1; head.next = blah。

使用new的原因是简单地创建该类型的“新”对象。通常用于动态的东西,在这种情况下它看起来像某种链接列表,所以是的,你需要新的。但是对于每一个新的,你需要在完成后删除数据 否则你会有内存泄漏,在这种情况下,列表越大,你就不会解构不再需要的东西,它会浪费更多的内存。

但是,您根本不需要使用任何此代码。相反,标准库中已经有一个容器提供这种类型的支持,另外还有额外的支持。

#include <list> 
// and use
std::list<type> data;

您可以轻松地在此列表中插入和删除数据,它将为您处理分配和解除分配;这意味着你不需要使用new或delete,你可以放心地假设将为你管理内存,并且不会有内存泄漏。