在这种情况下,我可以重复使用指针吗?

Can I re-use a pointer in this case?

本文关键字:指针 这种情况下 我可以      更新时间:2023-10-16

假设:

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
}

既然指针被删除,难道是否存在重复使用的问题?

至于您的原始问题:是的,您可以将其重新分配给这样的指针。指针只有一个内存地址,仅此而已。

但是您实际上不应该这样做,因为处理这样的原始指针可能会导致错误,因此您已经有一些代码中的一些。现代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包装器代替了它们。这有一些优点:

  1. 您显然是所有权,unique_ptr只能由当前范围拥有。当CreateObj创建对象时,通过返回临时(无名)unique_ptr,它会释放所有权,从而可以随时删除呼叫者。这将避免棘手的memleaks。
  2. 删除会自动为您发生,无论 unique_ptr脱离范围或被覆盖时(例如,由分配运算符)。

是的,您可以重复使用指针。指针只是一种参考对象的方法。由于您删除对象,因此您可以随意将指针用于所需的任何内容。

这样做肯定没有问题。指针只是地址容器(类似于包含值的变量)。

new分配一个对象并返回地址。然后,您只需将结果地址分配给所需的任何指针,无论是delete d指示器,持有"现有"分配的对象的指针,无效的指针还是非初始化的指针。

只要先前分配的内存被首先分配给您,就没有问题,就像您已经在代码中所做的那样。

当您delete指针时,您实际上可以释放其指向的内存。指针的值(该内存的起始地址)是没有变化的,直到您通过pointer = NULLpointer = new ..

重新分配它

您可以重复使用指针,因为您从未删除指针;您删除了指针指向的Obj。请记住,指针正在存储一个内存地址。因此,就像您可以将INT更改为不同的值一样,您总是可以将指示器更改为记住或指向其他内存地址。另外,当您在foo.pObj上执行删除操作时,您并不是说" delete foo.pobj"。相反,您是在说"删除foo.pobj指向的obj"。

如果您尝试对foo.pObj执行delete操作后指向的对象,则出现问题。