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

问题描述 投票:0回答:6

假设:

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++ pointers delete-operator
6个回答
3
投票

至于你原来的问题:是的,你可以重新分配给这样的指针。指针仅保存内存地址,仅此而已。

但是你实际上不应该这样做,因为像这样处理原始指针可能会导致错误,你的代码中已经有一些错误了。现代 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
    超出范围或被覆盖(例如被赋值运算符)时,删除会自动发生。

1
投票

是的,您可以重复使用指针。指针只是引用对象的一种方式。由于您删除了该对象,因此您可以随意使用指针来完成您需要的任何操作。


1
投票

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

new
分配一个对象并返回一个地址。然后,您可以将结果地址分配给您想要的任何指针(正确类型),无论它是
delete
d 指针、保存“现有”已分配对象的指针、保存 NULL 的指针还是未初始化的指针。


0
投票

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

当你

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

重新分配它

0
投票

您可以重复使用该指针,因为您从未删除过该指针;您删除了指针所指向的

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

如果您在执行

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


0
投票

是的,您可以重复使用它。 但就内存安全而言,存在一种可能的安全隐患。这是一个非常极端的情况。对于大多数应用程序来说,这不应该是一个问题。但在安全保障方面,你必须了解各方面的限制。

假设您的应用程序已经运行了很长时间,如果它经常重复使用相同的内存地址(指针重复使用)来绑定新对象,则某些恶意行为者有可能将任意代码/执行点注入到该特定对象上指针地址将使您的应用程序执行其代码,而不是应用程序附带的原始代码。

删除一个对象并将其设置为“nullptr”并通过调用 new 或任何其他奇特方法再次重新创建它后,该新分配可能会驻留在与前一个指针变量的地址不同的内存位置上(没有但可以保证,因为这样做是操作系统的责任(找到创建新对象等的适当位置)。

© www.soinside.com 2019 - 2024. All rights reserved.