Sign in to follow this  
Ruzhyo2000

Question about using new and delete...

Recommended Posts

I made a simple test program using C++, just to test the behavior of pointers to get a better understanding. I created a pointer and initialized it to null. When I std::cout'd the pointer, it said "NULL." Then, I used new to create a new custom object. When I std::cout'd the pointer, it gave me an address. Lastly, I used delete to delete the object pointed to by the pointer. When I std::cout'd the pointer this time, it still gave me the same address. My question here is, can the memory at the address stored in this pointer still be used by other, unrelated variables or objects, if the object that was previously there has been deleted? Lets say, after some time, I called delete with this pointer without creating another object at it using new, would it delete the data stored in this memory belonging to other variables or objects? If this is not the case, then wouldn't this memory technically still be in use, even if nothing is stored there? I ask this because one of the objects I am creating for my game uses dynamic memory. Depending on the status of the custom class I have created, it may or may not have data stored at the address held in the pointer (if there even is one). However, in the destructor, I call delete for this pointer. Could this have unintended consequences?

Share this post


Link to post
Share on other sites
Quote:
Original post by Ruzhyo2000
I made a simple test program using C++, just to test the behavior of pointers to get a better understanding.

I created a pointer and initialized it to null. When I std::cout'd the pointer, it said "NULL." Then, I used new to create a new custom object. When I std::cout'd the pointer, it gave me an address. Lastly, I used delete to delete the object pointed to by the pointer. When I std::cout'd the pointer this time, it still gave me the same address.

Delete won't change the value of the pointer, however the value of the pointer after delete has been performed will be invalid. In general most people will assign 0 to the pointer after deleting it just as a sanity check.

In general though you should attempt to use smart pointers, such as boost::shared_ptr and std::auto_ptr, and standard containers over raw pointers.
Quote:
My question here is, can the memory at the address stored in this pointer still be used by other, unrelated variables or objects, if the object that was previously there has been deleted? Lets say, after some time, I called delete with this pointer without creating another object at it using new, would it delete the data stored in this memory belonging to other variables or objects? If this is not the case, then wouldn't this memory technically still be in use, even if nothing is stored there?

Sure, any subsequent new's can use the memory you've just released.
Quote:
I ask this because one of the objects I am creating for my game uses dynamic memory. Depending on the status of the custom class I have created, it may or may not have data stored at the address held in the pointer (if there even is one). However, in the destructor, I call delete for this pointer. Could this have unintended consequences?

Not really, if you delete the object in the destructor then you aren't worried about using that pointer again accidentally because its owning class is being destroyed.


class Safe {
int* p;
public:
Safe() : p(new int) {}
~Safe() { delete p; }
};

class Unsafe {
int* p;
public:
Unsafe() : p(new int) {}
void Clear() { delete p; }
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Ruzhyo2000
Lastly, I used delete to delete the object pointed to by the pointer. When I std::cout'd the pointer this time, it still gave me the same address.

Right, because delete does not change the pointer. That's why it's considered good practice do set the pointer to 0 after delete IF the pointer is going to stay around for a while after the deletion of the pointee.

Quote:
Original post by Ruzhyo2000
My question here is, can the memory at the address stored in this pointer still be used by other, unrelated variables or objects, if the object that was previously there has been deleted?

Yes. The runtime system does not know that pointers are still pointing to things that got deleted. You simply aren't allowed to access deleted stuff anymore - if you do, you are in undefined behavior land.

Share this post


Link to post
Share on other sites
I see. For further clarification, I'll provide an example.

class SomeObject
{
// SomeObject is defined here.
}

class OtherObject
{
SomeObject* ptr;
public:
Object(){ ptr = new SomeObject; }
~Object(){ delete ptr; }
void make() { ptr = new SomeObject; }
void destroy() { delete ptr; }
};


In this case, lets say OtherObject has member functions that throw exceptions if the SomeObject has not been declared with new or if it has been deleted. What I am wondering now is, if OtherObject::destroy() is called, and then, later on in runtine, OtherObject becomes out of scope and it's destructor is called ( deleting ptr again ) will this delete other variables or other random objects that have been created in memory at the location that ptr still points to? (In effect not only performing the unecessary task of deleting a pointer that has already been deleted, but potentially screwing up completely unrelated objects current in use).

I guess I could say 'ptr = NULL;' after every delete, but I am worried about the possibility that I might forget to do this (and unsure at this point if it is a necessity).

I would like to know more about these smart pointers. I assume they provide functionality that helps prevent someone from screwing up these dynamic memory allocations?

Share this post


Link to post
Share on other sites
A better explination than your example would be these quick snippits:

int *x = new int;
delete x;
delete x; // << this will outright crash the program

int *y = new int;
delete y;
y = NULL;
delete y; // << deleting a null pointer is safe

int *x = new int;
delete x;
int *y = new int;
delete x; // << this MAY or MAYNOT crash the program. if y just happens to == x delete will happily chug along.

int *x = new int[10];
delete x; // << no good, you have to use delete[]
int *y = new int;
delete[] y; // << no good, you have to use delete

int x;
int *y = &x;
delete x; // << no good, you can only delete what you new and delete[] what you new[]. BUT a pointer can point to anything, even something on the stack.






This is preferable, as it follows RAII, and is easy to manage (but as Washu said, a smart pointer would be significantly better):

class OtherObject
{
SomeObject* ptr;
public:
OtherObject(){ ptr = new SomeObject; }
~Object(){ delete ptr; }
private:
OtherObject( OtherObject &other ) {} // private copy constructors because copying this object would be really bad
OtherObject( const OtherObject &other ){}
}








This is not, as it requires a lot more thought and manual management:

class OtherObject
{
SomeObject* ptr;
public:
void make() { ptr = new SomeObject; }
void destroy() { delete ptr; }
};







Share this post


Link to post
Share on other sites
Quote:
Original post by Ruzhyo2000
if OtherObject::destroy() is called, and then, later on in runtine, OtherObject becomes out of scope and it's destructor is called ( deleting ptr again )

Calling delete twice on the same pointer yields undefined behavior. DON'T DO IT.

Quote:
Original post by Ruzhyo2000
I guess I could say 'ptr = NULL;' after every delete

You don't have to, just do it after the delete in destroy, but not in the delete in the destructor.

Quote:
Original post by Ruzhyo2000
but I am worried about the possibility that I might forget to do this

Then use modern C++ instead of manually newing and deleting everything.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this