//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;
}
delete [] question (SOLVED)
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?
[Edited by - Vampyre_Dark on June 21, 2005 8:19:41 AM]
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
Mark
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.
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.
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.
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:
or
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
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
It tend to write code like that as
so the pointers are null after the delete.
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.
Quote:Original post by FrunyI 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.
Note, however, that you do not have to guard against deleting NULL pointers - it's a no-op.
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 MauManNice.
It tend to write code like that as
*** Source Snippet Removed ***
so the pointers are null after the delete.
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.
Not all that nice. It will save you in a few situations, but not many. Wrapped pointers are much safer:
Enigma
Quote:Original post by Vampyre_DarkQuote:Original post by MauMan
It tend to write code like that asdelete [] 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
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.
Quote:Original post by Enigma(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]
what is the problem?
Thanks to all who answered, it's solved, and no more crashes on exit.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement