节点 *temp; 和节点 *tmp = 新节点之间的差异

Diffrence between node *temp; and node *tmp = new node;

本文关键字:节点 之间 新节点 temp tmp      更新时间:2023-10-16
struct node
{
int data;
node *next;
} * save;

谁能解释一下下面的声明之间有什么区别,基于堆栈和堆的内存分配是它们之间或任何其他声明之间的唯一区别吗? 我们可以将它们都称为对象指针吗?

node *temp;

node *tmp = new node;

new 运算符表示在免费存储上分配内存的请求。如果有足够的内存可用,new 运算符将初始化内存,并将新分配和初始化的内存的地址返回给指针变量。

使用 new 运算符的语法:要分配任何数据类型的内存,语法为:

pointer-variable = new data-type;

在这里,指针变量是数据类型类型的指针。数据类型可以是任何内置数据类型,包括数组或任何用户定义的数据类型,包括结构和类。 例:

// Pointer initialized with NULL
// Then request memory for the variable
int *p = NULL; 
p = new int;   
OR
// Combine declaration of pointer 
// and their assignment
int *p = new int;

在您的示例中,node* temp创建一个具有自动存储node*类型的对象(请参阅存储持续时间(。 在第一行中,此对象未初始化,在第二行中,使用指向位于动态存储中的node类型的对象的指针对其进行初始化。

因此,在第一个示例中,实际上不存在类型node的对象。您只创建了一个指针,该指针以后可能会引用此类对象。 在任何情况下,当名为temp的对象的生存期结束时(即作用域结束时(,只会销毁指针对象,而不会销毁指针可能指向的对象。

请注意,您不能访问不存在的对象的成员,因此temp->data如果temp不指向类型为node的对象,则将显示未定义的行为。

嗯,它们都是指向对象的指针,特别是node。现在,指针本身,即*temp*tmp都是堆栈分配的变量,能够保存可以指向node类型的对象的内存地址。

这两个指针都能够保存运行时在堆上创建的动态分配node对象的地址,以及在编译时创建的堆栈上的本地对象的地址。

node stack_alloc_node; 
node* n;

在这里,n在编译时在堆栈上分配,它能够保存任何node对象的地址; 我可以这样做:

n = &stack_alloc_node;

stack_alloc_node在编译时在堆栈上创建,现在n保存对它的引用。 现在,让我们谈谈new.如果要在运行时为对象动态分配内存,请执行以下操作:

new node;

new要求操作系统提供内存,并由操作系统提供内存块。 然后new返回此内存的地址。在运行时创建的任何内存只能通过指针引用,因此为了将该内存块的地址存储在某处,我们需要指针:

node* temp = new node;

未赋值的指针变量称为野生指针,因为它可能包含无用的任意地址。

以下是 3 个要素:

node n1;

n1是在编译时创建的堆栈分配的node对象。

new node()

这是对计算机的指令,要求内存并通过调用node的构造函数在该内存上创建新的node对象,然后返回该内存的地址。

node* n2;

n2是在堆栈上分配的指针变量,尚未分配,因此是野生的。此指针能够保存nodes 分配的堆和堆栈分配的地址。您可以执行以下两项操作:

n2 = new node();
n2 = &n1;

在第一种情况下,必须存储对新获得的内存的引用,这就是第一个语句中n2的目的。第二条语句也是有效的,因为n2仍然被分配了一个指针,但分配给node堆栈。 但是,以前的代码块存在内存泄漏,因为对使用堆上的new node()新创建的node的所有引用都将丢失。您应该始终:

delete n2;

以在将指针分配给另一个地址之前释放关联的内存。您无需删除在堆栈上创建的对象,因为当控制超出范围时,它们会自动销毁。堆分配的对象不是这种情况,需要显式删除它们。在 Java 和 C# 等语言中,这由垃圾回收子系统自动处理。但C++没有。如果您希望自动处理内存,可以在此处阅读有关智能指针的信息。