假设:
struct Foo
{
Obj* pObj;
Foo() : pObj(NULL);
};
Obj* CreateObj()
{
//do some stuff and then
return new Obj; //obj is a class
}
int main()
{
Foo foo;
foo.pObj = CreateObj();
DoSomeOperationWithTheObj( foo.pObj );
//suppose foo is a monster that should be 'killed' or deleted now
delete foo.pObj;
foo.pObj = NULL;
//the question is can this pointer be 're-used' now like this:
foo.pObj = CreateObj(); //create another object
}
由于指针被删除了,重新使用它是不是有问题呢?
答案 0 :(得分:3)
至于你原来的问题:是的,你可以重新分配这样的指针。指针只包含一个内存地址,仅此而已。
但是你实际上不应该这样做,因为像这样处理原始指针会导致错误,你的代码中已经有一些错误。现代C ++允许您以更好的方式做到这一点而无需担心。假设我们从这个(可编译的)代码开始,我用一个int替换了Obj,但是它是一个本机类型而不是一个类并不重要:
#include <iostream>
struct Foo
{
int* pObj;
Foo() : pObj(NULL) {}
};
int* CreateObj()
{
return new int(42); //obj is a class
}
int main()
{
Foo foo;
foo.pObj = CreateObj();
std::cout << *foo.pObj << std::endl;
delete foo.pObj;
foo.pObj = new int(13);
std::cout << *foo.pObj << std::endl;
delete foo.pObj;
}
我们可以将其转换为以下内容:
#include <iostream>
#include <memory>
struct Foo
{
std::unique_ptr<int> pObj;
Foo() : pObj(NULL) {}
};
std::unique_ptr<int> CreateObj()
{
return std::unique_ptr<int>(new int(42));
}
int main()
{
Foo foo;
foo.pObj = CreateObj();
std::cout << *foo.pObj << std::endl;
foo.pObj = std::unique_ptr<int>(new int(13));
std::cout << *foo.pObj << std::endl;
}
请注意,主要的变化是我删除了原始指针并将其替换为unique_ptr
包装器。这有一些好处:
unique_ptr
只能归当前范围所有。当createObj创建对象时,通过返回临时(无名)unique_ptr
,它释放所有权,以便调用者可以随时删除它。这将避免棘手的memleaks。unique_ptr
超出范围或被覆盖时(例如通过赋值运算符),删除会自动发生。答案 1 :(得分:1)
是的,您可以重复使用指针。指针只是引用对象的一种方式。由于删除了对象,因此可以随意使用指针。
答案 2 :(得分:1)
这样做肯定没有问题。指针只是地址的容器(类似于包含值的变量)。
new
分配一个对象并返回一个地址。然后,您可以将结果地址分配给您想要的任何指针(正确类型),是否可能是delete
指针,指向“现有”分配对象的指针,NULL保持指针或未初始化指针。
答案 3 :(得分:0)
重复使用指针没有问题,只要首先释放先前分配的内存,就像您在代码中所做的那样。
当你delete
一个指针时,你实际上释放了它指向的内存。指针的值(该内存的起始地址)保持不变,直到您按pointer = NULL
或pointer = new ..
重新分配
答案 4 :(得分:0)
您可以重复使用指针,因为您从未删除指针;你删除了指针所指向的Obj
。请记住,指针正在存储内存地址。因此,就像您可以将int更改为其他值一样,您始终可以将指针更改为记住或指向不同的内存地址。此外,当您在foo.pObj
上执行删除操作时,您不是说“删除foo.pObj”。相反,你说“删除foo.pObj所指向的Obj”。
如果您在执行foo.pObj
操作后尝试对delete
指向的对象执行某些操作,则会出现问题。