【问题标题】:Can I re-use a pointer in this case?在这种情况下我可以重复使用指针吗?
【发布时间】:2012-10-23 05:13:17
【问题描述】:

假设:

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
}

既然指针被删除了,重用它不是有问题吗?

【问题讨论】:

  • 不要将指针与其“指向”的对象混淆。
  • 是的,您可以将指针重新分配给新的/不同的对象
  • 指针就像任何其他变量一样,如果您不再将它用于其他任何事情,您可以将它重用于任何用途。你不会问它是否是一个普通的int 变量,对吧? ;)
  • @ViniyoShouta 不,你不应该(回应你对 pst 评论的回复)。
  • 相关问题(同样的问题,但针对 C)stackoverflow.com/questions/504948/…

标签: c++ pointers delete-operator


【解决方案1】:

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

但您实际上不应该这样做,因为像这样处理原始指针可能会导致错误,您的代码中已经有一些错误。现代 C++ 允许您以更好的方式做到这一点而无需担心。假设我们从这个(可编译的)代码开始,我将 Obj 替换为一个 int,但它是本机类型而不是类这一事实并不重要:

#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 它释放所有权,因此调用者可以随时删除它。这将避免棘手的内存泄漏。
  2. unique_ptr 超出范围或被覆盖(例如,被赋值运算符)覆盖时,会自动为您删除。

【讨论】:

    【解决方案2】:

    是的,您可以重复使用指针。指针只是引用对象的一种方式。由于您删除了对象,因此您可以随意使用指针来满足您的需要。

    【讨论】:

      【解决方案3】:

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

      new 分配一个对象并返回一个地址给它。然后,您可以将结果地址分配给您想要的任何指针(适当类型的),无论它可能是 deleted 指针、持有“现有”分配对象的指针、持有 NULL 的指针或未初始化的指针。

      【讨论】:

        【解决方案4】:

        重复使用指针没有问题,只要先释放先前分配的内存,就像您在代码中所做的那样。

        当你 delete 一个指针时,你实际上释放了它指向的内存。指针的值(该内存的起始地址)保持不变,直到您通过pointer = NULLpointer = new .. 重新分配它

        【讨论】:

          【解决方案5】:

          您可以重用指针,因为您从未删除过指针;您删除了指针指向的Obj。请记住,指针正在存储内存地址。因此,就像您可以将 int 更改为不同的值一样,您始终可以更改指针以记住或指向不同的内存地址。此外,当您对foo.pObj 执行删除操作时,您并不是在说“删除 foo.pObj”。相反,您说的是“删除 foo.pObj 指向的 Obj”。

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

          【讨论】:

            猜你喜欢
            • 2016-11-07
            • 2012-03-28
            • 1970-01-01
            • 1970-01-01
            • 2016-09-12
            • 2022-08-05
            • 2015-09-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多