Jump to content
  • Advertisement
Sign in to follow this  
Daaark

delete [] question (SOLVED)

This topic is 4803 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What value does a variable get set too after you use the delete operator on it? I've been using this, for awhile, but it started bombing on me when some of my destructors were running at app exit. I know you are not supposed to delete stuff twice, but how do you check?
//This stuff would have already been nuked via my Kill() member function
//I keep stuff like this, simply as a backup.
c_model::~c_model()
{
    //delete the model data if it hasn't already happened
    if (m_vtx != NULL) delete [] m_vtx;
    if (m_nrm != NULL) delete [] m_nrm;
    if (m_uvw != NULL) delete [] m_uvw;
    if (m_tri != NULL) delete [] m_tri;
        
    return;
}

[Edited by - Vampyre_Dark on June 21, 2005 8:19:41 AM]

Share this post


Link to post
Share on other sites
Advertisement
delete[] does not affect the value of a pointer variable; the pointer retains is previous value, but the memory it points to is not valid any more, so you should not dereference it. You can manually set it to 0 if you like.

Mark

Share this post


Link to post
Share on other sites
Quote:
Original post by Vampyre_Dark
What value does a variable get set too after you use the delete operator on it?


It is undefined. From your code snippet, you seem to be assuming it will get set to 0. It is not the case: you would have to do that yourself. Note, however, that you do not have to guard against deleting NULL pointers - it's a no-op.

Quote:
I know you are not supposed to delete stuff twice, but how do you check?


After the fact, you can't. Set the pointer to 0 yourself when you've deleted the object if you're afraid you might delete it twice.

Share this post


Link to post
Share on other sites
delete doesn't set it to anything. The value of the pointer will still be the same, just the memory it points to doesn't belong to you any more. Calling delete on it a second time will cause a crash.

Set your pointers to 0 (or NULL) after you've deleted them, then it's easy to check whether they're valid or not.

EDIT: heh, beaten twice.

Share this post


Link to post
Share on other sites
You take responsibility for checking, either by ensuring that each new'ed pointer is only owned by one class, or by always duplicating pointed-to data on copy, or by keeping a reference count, or some other scheme. Without more information about your design I can't say what would be best for your situation, but I suspect either a single owner of the data, with other objects using references to that data, or a boost::shared_ptr to a vector:
class ModelData
{
// members
std::vector< gl::Vector > vertices_;
// etc.
};
std::map< std::string, ModelData > models;
class Model
{
// members
ModelData const & model_;
};

or
class Model
{
// members
boost::shared_ptr< std::vector< gl::Vector > > vertices_; // really ought to typedef this
// etc
};

For the first you are responsible for adding models to the models map the first time they are needed and removing the entry from models when a specific model is not longer needed. For the second you are responsible for creating new vectors for the data each time a new model is created, but that model can then be copied to your hearts content. The second method will also handle deallocation for you when the Model is destructed.

By the way, there is no need to check for null before delete([])ing. delete([])ing a null pointer is defined to be a noop by the standard.

Enigma

Share this post


Link to post
Share on other sites
It tend to write code like that as


delete [] m_vtx, _vtx = 0;
delete [] m_nrm, _nrm = 0;
delete [] m_uvw, _uvw = 0;
delete [] m_tri, _tri = 0;



so the pointers are null after the delete.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Note, however, that you do not have to guard against deleting NULL pointers - it's a no-op.
I read somewhere in the last few days that you should NEVER delete stuff twice, and it could be disasterous. [lol] However, I have no clue where that was. Could have been MSDN or somewhere else. It was some official documentation, I remember that much.

Removing the extra delete in my deconstructors stopped the crashes. I'll start manually setting my stuff to NULL from now on.

Quote:
You take responsibility for checking, either by ensuring that each new'ed pointer is only owned by one class, or by always duplicating pointed-to data on copy, or by keeping a reference count, or some other scheme. Without more information about your design I can't say what would be best for your situation, but I suspect either a single owner of the data, with other objects using references to that data, or a boost::shared_ptr to a vector:
???I'm doing nothing near that complicated. [lol] Just trying to clean up properly. The c_models aren't apart of any hierarchy or anything. I just load 'em and draw 'em as needed.

Quote:
Original post by MauMan
It tend to write code like that as

*** Source Snippet Removed ***

so the pointers are null after the delete.
Nice.

Share this post


Link to post
Share on other sites
If your models are not part of a hierarchy then what is the problem? Allocate in the constructor and deallocate in the destructor. Better yet, use vectors and don't worry about the deallocation.
Quote:
Original post by Vampyre_Dark
Quote:
Original post by MauMan
It tend to write code like that as
delete [] m_vtx, _vtx = 0;
delete [] m_nrm, _nrm = 0;
delete [] m_uvw, _uvw = 0;
delete [] m_tri, _tri = 0;

so the pointers are null after the delete.

Nice.

Not all that nice. It will save you in a few situations, but not many. Wrapped pointers are much safer:
#include <vector>
#include <boost/shared_ptr.hpp>

class SetToNull
{
public:
SetToNull()
:
array_(new int[12])
{
}
~SetToNull()
{
delete[] array_;
array_ = 0;
}
private:
int * array_;
};

class UseWrapped
{
public:
UseWrapped()
:
array_(new std::vector< int >(12))
{
}
private:
boost::shared_ptr< std::vector< int > > array_;
};

int main()
{
{
SetToNull stn1;
SetToNull stn2(stn1);
} // BANG! double deletion
{
UseWrapped uw1;
UseWrapped uw2(uw1);
} // OK.
}


Enigma

Share this post


Link to post
Share on other sites
If you have zeroed the pointer, you can safely call delete/delete[] as many times as you want. But like other have said before, the actual return from delete/delete[] is undefined. Which means the results of calling delete/delete[] a second time without zeroing it is also undefined.

Share this post


Link to post
Share on other sites
Quote:
Original post by Enigma
what is the problem?
(not to be rude, I appreciate what you posted for me) It has nothing to do with what I asked. I didn't ask about boost, or vectors, or smart pointers. I asked about delete keyword specific functionality. [embarrass]

Thanks to all who answered, it's solved, and no more crashes on exit.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!