Reputation: 15746
Suppose:
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
}
Since the pointer was deleted, isn't there a problem re-using it right?
Upvotes: 1
Views: 2959
Reputation: 398
Yes you can reuse it. But there is one possible security implication in terms of memory safety. This is a very edge-case scenario. And this shouldn't be a concern for most apps. But you must know the limit from all sides when it comes to security and safety.
Suppose your application has been running since a long time, if it frequently keeps reusing the same memory address (pointer re-use) to bind a new object there is a chance that some malicious actor can inject arbitrary code/execution point onto that specific pointer address that will make your application execute their code instead of the original one that came with the application.
After you delete an object and set it to 'nullptr' and the re-create it again by calling new or any other fancy method, that new allocation will likely reside onto a different memory location than the address of the previous pointer variable (no guarantee though because it's OS's responsibility to do so (finding appropriate location for creating new object etc)).
Upvotes: 0
Reputation: 17176
As for your original question: yes, you can reassign to pointers like that. A pointer holds just a memory address and nothing more.
But you should not actually ever do this because handling raw pointers like this can lead to bugs, you already have a few of those in your code. Modern C++ allows you to do this way more nice and without concern. Suppose we start from this (compilable) code, i replaced Obj by an int, but the fact that it's a native type instead of a class does not matter:
#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;
}
We can convert this to the following:
#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;
}
Note that the major change is that I removed raw pointers and replaced them with the unique_ptr
wrapper. This has a few advantages:
unique_ptr
can only be owned by the current scope. While createObj creates the object, by returning the temporary (nameless) unique_ptr
it releases ownership so the caller can delete it whenever it wants. This will avoid tricky memleaks.unique_ptr
goes out of scope or when it is overridden (e.g. by the assignment operator).Upvotes: 3
Reputation: 17708
There is definitely no problem in doing that. Pointers are just containers of addresses (analogous to variables which contains values).
new
allocates an object and returns an address to it. You can then just assign the result address to any pointer (of the proper type) you want, whether it may be delete
d pointers, pointers holding "existing" allocated objects, NULL-holding pointers or uninitialized pointers.
Upvotes: 1
Reputation: 338
You can reuse the pointer because you never deleted the pointer; you deleted the Obj
that the pointer was pointing to. Keep in mind that a pointer is storing a memory address. So, just like you can change an int to a different value, you can always change a pointer to remember, or point, to a different memory address. Also, when you perform the delete operation on foo.pObj
, you are not saying "delete foo.pObj". Instead you are saying "delete the Obj that foo.pObj is pointing to".
Where a problem would arise is if you tried to do something to the object that foo.pObj
is pointing to after you performed the delete
operation.
Upvotes: 0
Reputation: 14505
There is no problem to reuse a pointer, as long as the memory previously allocated is deallocated first, as you already did in your code.
When you delete
a pointer, you actually free the memory it points to. The value of the pointer(the starting address of that memory) is unchanged, until you reassign it by pointer = NULL
or pointer = new ..
Upvotes: 0
Reputation: 3030
Yes, you can re-use the pointer. A pointer is just a way to refer to an object. Since you delete the object, you are free to use the pointer for whatever you need it.
Upvotes: 1