如果我创建一个节点,如下
struct node
{
char *ptr = (char *)malloc(sizeof(char));
}*current;
void main()
{
node *temp = new node();
current = temp;
}
上面的代码会自动将current->ptr
设置为temp->ptr
所指向的点吗?
struct node
{
char *ptr = (char *)malloc(sizeof(char)); // INVALID
} *current;
首先,您不应该混合使用内存模型。如果您使用的是new
,请坚持使用new
。不要在new
和malloc
之间弹跳。
其次,这不是有效的C++。不能在声明中声明类成员并调用函数对其进行初始化(除非使用C++11的新功能)。更新它以清理它看起来像:
struct node
{
char* ptr; // declare the pointer
node() : ptr(new char) { } // initialize the pointer in the constructor
// NOTE: should also add a copy constructor and copy-assignment operator here
~node()
{
delete ptr; // free the memory in the destructor
}
};
int main() // NOTE that main must return an int, not void
{
node current = new node();
node temp = *current; // will do a shallow copy
// ...
delete current;
// PROBLEM - temp now has a dangling pointer!
return 0;
}
还要注意,在这种情况下,ptr
没有理由必须是指针。由于您只是动态地分配一个char
,因此您可以使用自动:
struct node
{
char data;
node() : data(' ') { }
};
int main()
{
node current;
node temp = current; // temp now has a copy of data, no problems
return 0;
}
上面的代码会自动将current->ptr设置到temp->ptr正在指向
您拥有的代码甚至不会编译,但如果您进行了修复,默认的复制赋值操作符将进行浅层复制。在指针的情况下,这意味着有两个对象都指向同一个内存位置。由于他们都认为自己拥有它,所以当其中一方销毁它时,另一方就会留下一个悬空的指针。
current和temp引用内存中的同一位置。所以实际上current->ptr是temp->ptr。
在使用赋值运算符的语句之后
current = temp;
电流和温度将具有相同的值。此值是类型为node的对象的地址。因此,两个指针都指向对象占用的同一内存。对象本身未被复制或移动。
操作符new返回内存的地址,它在内存中分配了一个对象,而不是对象本身。所以在这个声明之后
node *temp = new node();
变量temp将有这个地址并且在之后
current = temp;
current和temp都将存储此地址。
是,current->ptr
和temp->ptr
引用相同的内存地址。当您通过node* temp = new node()
实例化节点对象时,临时指针指向新分配的存储。通过current = temp
分配current
指针将简单地使当前点指向该存储器位置。请注意,current
指向的对象仍然存在于内存中的其他位置(以及最大大小的字符数组),因为我们还没有释放该内存。此外,指针分配不会复制对象,它只是使指针指向不同的内存位置。事实上,引用current
和temp
指向的对象中的任何成员都会返回相同的值,无论它们是指针还是其他类型。
您的代码当前无效,将不会编译。这是你打算做的事情的固定版本。
#include<cstdlib>
#include<cstdio>
#define MAX 10
struct node
{
char* ptr;
node()
{
ptr = new char[MAX]; // Do not use malloc if using new elsewhere.
}
}*current;
int main()
{
struct node* temp = new struct node();
current = temp;
// The pointer addresses will be the same.
printf("Current->ptr=%p, temp->ptr=%pn", (void*)current->ptr, (void*)temp->ptr);
return 0;
}