Jump to content

  • Log In with Google      Sign In   
  • Create Account

Deleting value stored inside a pointer


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 Aluthreney   Members   -  Reputation: 256

Like
0Likes
Like

Posted 26 January 2013 - 05:49 PM

So my situation is the following:

 

I have a pointer array that is initiated as NULL. The idea is that this array of pointers will hold instances of a class, which I create using the new operator:

 

myClass *ptr[10];
for(int x; x<=9; x++){ptr[x]=NULL;}

code...code...code...
ptr[5]=new myClass;
 

So far everything works fine, but now I need to know how to delete the instance inside the pointer without deleting the pointer / pointer array, itself.

 

Your help is appreciated biggrin.png


Aluthreney -- the King of sheep.


Sponsor:

#2 Brother Bob   Moderators   -  Reputation: 8607

Like
1Likes
Like

Posted 26 January 2013 - 05:56 PM

You need to call delete for everything you call new for. You call new for ptr[x], for each x in the array, so you need to call delete for ptr[x] as well.
for(int x=0; x<10; ++x) {
    delete ptr[x];
}

Edited by Brother Bob, 26 January 2013 - 05:57 PM.


#3 fastcall22   Crossbones+   -  Reputation: 4463

Like
1Likes
Like

Posted 26 January 2013 - 05:58 PM

delete ptr[5];

You can't (shouldn't) delete ptr because it wasn't newed:
myClass** arr = new myClass*[10];
for ( auto& obj : arr )
    obj = new myClass();

// ...

for ( auto& obj : arr )
    delete obj;
delete[] arr;

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#4 Aluthreney   Members   -  Reputation: 256

Like
0Likes
Like

Posted 26 January 2013 - 07:07 PM

You need to call delete for everything you call new for. You call new for ptr[x], for each x in the array, so you need to call delete for ptr[x] as well.

for(int x=0; x<10; ++x) {
    delete ptr[x];
}

I tried doing this, but it didn't do anything. The class instance contains a 3d object that is rendered when I run the program. Supposedly, when I delete the contents inside the  pointer (using delete ptr[x]) the image wont render when I run the program, but it does...

 

delete ptr[5];

You can't (shouldn't) delete ptr because it wasn't newed:

myClass** arr = new myClass*[10];
for ( auto& obj : arr )
    obj = new myClass();

// ...

for ( auto& obj : arr )
    delete obj;
delete[] arr;

I don't want to delete the pointer only what it's pointing to.


Aluthreney -- the King of sheep.


#5 Brother Bob   Moderators   -  Reputation: 8607

Like
1Likes
Like

Posted 26 January 2013 - 07:13 PM

If you delete the objects you have allocated, but then keep using the objects afterwards, your program is ill-formed. That does not mean that your program must crash or must produce an incorrect result. It may do that, but it doesn't have to. Nevertheless, your program is ill-formed.



#6 Aldacron   GDNet+   -  Reputation: 3275

Like
0Likes
Like

Posted 26 January 2013 - 07:28 PM

Deleting something doesn't automatically set the pointer to null. You'll need to nullify it yourself.
delete ptr[x];
ptr[x] = NULL;
But if you take this approach, then you need to check for NULL every time you access the array.

#7 Brother Bob   Moderators   -  Reputation: 8607

Like
0Likes
Like

Posted 26 January 2013 - 07:39 PM

Deleting something doesn't automatically set the pointer to null. You'll need to nullify it yourself.

delete ptr[x];
ptr[x] = NULL;
But if you take this approach, then you need to check for NULL every time you access the array.

If you need to litter your code with null-checks, then you have ownership issues that needs to be solved instead. You should not ask yourself if you need to check for null before accessing a pointer, you should ask yourself why the pointer can be deleted in the first place if you still need it.



#8 Aluthreney   Members   -  Reputation: 256

Like
0Likes
Like

Posted 26 January 2013 - 08:09 PM




Deleting something doesn't automatically set the pointer to null. You'll need to nullify it yourself.

delete ptr[x];ptr[x] = NULL;
But if you take this approach, then you need to check for NULL every time you access the array.
If you need to litter your code with null-checks, then you have ownership issues that needs to be solved instead. You should not ask yourself if you need to check for null before accessing a pointer, you should ask yourself why the pointer can be deleted in the first place if you still need it.

If you delete the objects you have allocated, but then keep using the objects afterwards, your program is ill-formed. That does not mean that your program must crash or must produce an incorrect result. It may do that, but it doesn't have to. Nevertheless, your program is ill-formed.

I never said I was going to keep using the objects after I delete them. I said I was going to use the pointers and I don't want to delete the pointers, I want to delete what the pointers are pointing to.

Deleting something doesn't automatically set the pointer to null. You'll need to nullify it yourself.

delete ptr[x];ptr[x] = NULL;
But if you take this approach, then you need to check for NULL every time you access the array.
I was already planning for this though.
----------
Let me try and explain my idea.

I have two classes: class Monster and class Spawner.
The Monster class will have basic functions for movement, animations and keeping track of it's health, but it's the Spawner class that will control the creation and destruction of the Monster class instances.

So in the Spawner class I decided to create a pointer array of Monster class and also created two functions: createMonster() and killMonster().


//! definition of the createMonster() function...//! keep in mind that the pointer array has already been given the NULL value.
void createMonster()
{    
    while(int x; x<=9; x++)    
    {        
        if(ptr[x]==NULL)        
        {            
            ptr[x]= new Monster;        
        }    
    }
}


//! definition of the createMonster() function...
void killMonster(int x) //! the parameter is the particular pointer in the array that I want to clear.
{    
    code...code...code...    
    //! The line of code that will destroy the instance of the Monster class so that I can make the pointer NULL, in order to be re-    
    //! utilized at a later date to hold a new instance of the Monster class, goes here.    
    ptr[x]=NULL;
}
The code might look a bit empty, but I stripped it down to the bare bones in order to clarify the idea I'm trying to convey.

Edited by Aluthreney, 26 January 2013 - 08:18 PM.

Aluthreney -- the King of sheep.


#9 thade   Members   -  Reputation: 1652

Like
0Likes
Like

Posted 26 January 2013 - 08:26 PM

Others have a handle on the specifics, but I saw some terminology mix-ups here that I wanted to ensure weren't holding you up as well. (I see them all the time with people learning C/C++.)

 

I have a pointer array that is initiated as NULL. The idea is that this array of pointers will hold instances of a class, which I create using the new operator...

So far everything works fine, but now I need to know how to delete the instance inside the pointer without deleting the pointer / pointer array, itself.

Your array of pointers won't "hold instances of a class". It will hold pointers: a list of addresses were instances of your class can be held. When you invoke the new operator, it instantiates whatever class you pointed it at and returns the address where that instance lives, which you land in your array of pointers there.
 

As others have explained, when you invoke the delete operator on an address, the delete operator will kill the instance of your class that lives there. This is where things can get tricky at times and is why you need to know the full picture here.

 

If you delete an instance but reference it later (because you still have the address in that pointer array) you'll get a seg fault; it's why it's a good idea to set a pointer to null after you delete it. This stuff can also be the source of memory leaks (if you lose that pointer before you delete the memory you allocated with new, that memory is never released and just hangs out, dead and wasting space.

 

I hope this is helpful. <3 Good luck.


I was previously serratemplar; a name I forfeited to share a name with an angry rank-bearing monkey.

http://thadeshammer.wordpress.com/


#10 Brother Bob   Moderators   -  Reputation: 8607

Like
1Likes
Like

Posted 26 January 2013 - 08:43 PM





Deleting something doesn't automatically set the pointer to null. You'll need to nullify it yourself.

delete ptr[x];ptr[x] = NULL;
But if you take this approach, then you need to check for NULL every time you access the array.
If you need to litter your code with null-checks, then you have ownership issues that needs to be solved instead. You should not ask yourself if you need to check for null before accessing a pointer, you should ask yourself why the pointer can be deleted in the first place if you still need it.

If you delete the objects you have allocated, but then keep using the objects afterwards, your program is ill-formed. That does not mean that your program must crash or must produce an incorrect result. It may do that, but it doesn't have to. Nevertheless, your program is ill-formed.

I never said I was going to keep using the objects after I delete them. I said I was going to use the pointers and I don't want to delete the pointers, I want to delete what the pointers are pointing to.
The term "delete a pointer" means just that; you delete the object the pointer points to. That is, delete ptr does not delete ptr itself, it delete what ptr points to.

#11 Aluthreney   Members   -  Reputation: 256

Like
0Likes
Like

Posted 27 January 2013 - 05:39 AM

Ok I got it working thank you everyone for your advice, it really helped. Just one last question though: Even though the instance of the Monster disappears on screen (3d object is not rendered), is there a way to make sure the memory that was holding the instance is properly "cleaned"?


Aluthreney -- the King of sheep.


#12 Brother Bob   Moderators   -  Reputation: 8607

Like
0Likes
Like

Posted 27 January 2013 - 05:51 AM

If you called delete on it, the memory of the object the pointer points to have been deleted. Furthermore, the destructor for the object will also be called before the actual memory is released so you can do additional cleanup there so no indirect resources are leaked.

Edited by Brother Bob, 27 January 2013 - 05:51 AM.


#13 Bacterius   Crossbones+   -  Reputation: 9287

Like
0Likes
Like

Posted 27 January 2013 - 05:52 AM

Ok I got it working thank you everyone for your advice, it really helped. Just one last question though: Even though the instance of the Monster disappears on screen (3d object is not rendered), is there a way to make sure the memory that was holding the instance is properly "cleaned"?

 

No. It depends on the runtime and the operating system. For all you know it could be cached somewhere else in memory, or even in the swapfile on disk. But you should not have to even care what happened to the underlying memory, as long as you properly issued the delete statement indicating you no longer require use of this instance (unless you need it to be securely deleted, for security reasons or whatever).

 

In other words, if you've deleted the appropriate pointers, your worries end right there. From your perspective, everything happening at a lower level is assumed to work.


Edited by Bacterius, 27 January 2013 - 05:58 AM.

The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#14 SiCrane   Moderators   -  Reputation: 9670

Like
0Likes
Like

Posted 27 January 2013 - 05:54 AM

Depending on your platform and compiler you may be able to use a leak detector to determine if all your dynamically allocated memory has been properly freed. This thread contains some options. For non-memory resources there may be other tools available to check if they've been freed. (Ex: the DirectX debug runtimes will give you warnings if you haven't released everything and Windows Application Verifier can be used to detect leaked OS handles.)

#15 DavidWolfire   Members   -  Reputation: 184

Like
0Likes
Like

Posted 27 January 2013 - 12:09 PM

If you call delete(ptr[5]), it is telling the OS that you no longer need the memory pointed to by ptr[5]. However! delete() will not re-initialize that memory for you. You can think of it like a sand castle -- when you call new(), you draw a square on the beach to mark off the area you will use for your castle. Inside the square, the sand starts out in some random state, all lumpy with footprints from everyone else walking all over the beach. Then you use a constructor or initializer to shape the memory, forming your sand castle. Since you have your lines drawn in the sand, everyone else avoids your sand castle, and only you are allowed to touch it.

 

When you call delete(), you erase the lines in the sand. Your sand castle is still there, and you can still point to it, but it is no longer marked as off limits for others. Eventually people will start walking through it and claiming that sand for themselves, and moving pieces of your castle around to make their own. You can still point to the spot your castle used to be at, but your castle may or may not still be there -- it could also contain bits and pieces of random castles created by other people.

 

In this metaphor, your question would be "How do I make my sand castle perfectly flat when I'm done with it?" You could do that using something like memset(ptr[5], 0xDD, sizeof(MyClass)), to overwrite all the memory used by MyClass to 0xDD, so that you can more easily detect if something is trying to access freed memory. This is a fairly advanced memory debugging technique though, which is only really useful if you are trying to track down a memory corruption error. Otherwise, re-initializing memory when deleting a pointer is a waste of developer and execution time.

 

You should also be aware that nobody else is re-initializing their memory when they free it, so whenever you block off some memory with malloc() or new(), it will start out in a random state -- it will not be nicely zeroed like you might expect. If you call int* test = new int, then *test will usually not equal zero. It will probably be some strange number, like -842150451, because that's what it was set to when some other function or program freed it.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS