|
|
 |
 |
 |
 |
Deallocating Individual Elements of an Array Allocated Using new[]
I need to be able to allocate large numbers of elements at a time but then delete them one at a time. I have settled on the design of using new[] to allocate many items at once, but am unsure what is legal/ illegal about deallocation. Here's an example of what I would like to do: int *x = new int[1000]; ... delete x; ... delete x+1; ... delete x+2; ... ... delete x+999; Can I do this? Or do I have to delete the entire allocated array in one chunk using delete[]? This example is not entirely accurate as I would like the ordering of deletes to be more or less arbitrary. Any help is greatly appreciated. Thanks, -Chris PS - If you want to know why I want this done - it's because I want to save time allocating many objects instead of just one at a time and I'll be passing pointers to these objects to many different functions and places which will use them for awhile and then want to be able to delete them.
Chris Portka <chrispor@gmail.com> wrote in news:1181068806.363287.230290@o11g2000prd.googlegroups.com: > I need to be able to allocate large numbers of elements at a time but > then delete them one at a time. I have settled on the design of using > new[] to allocate many items at once, but am unsure what is legal/ > illegal about deallocation. Here's an example of what I would like to
What you new[], you must delete[]. What you new you must delete. Never mix them. > do: > int *x = new int[1000]; > ... > delete x; > ... > delete x+1; > ... > delete x+2; > ... > ... > delete x+999; > Can I do this? Or do I have to delete the entire allocated array in > one chunk using delete[]? This example is not entirely accurate as I
One chunk, using delete[]. You new[]'ed it, you delete[] it.
> would like the ordering of deletes to be more or less arbitrary. Any > help is greatly appreciated. Thanks, > -Chris > PS - If you want to know why I want this done - it's because I want to > save time allocating many objects instead of just one at a time and > I'll be passing pointers to these objects to many different functions > and places which will use them for awhile and then want to be able to > delete them.
On Jun 5, 3:40 pm, Chris Portka <chrispor@gmail.com> wrote:
> I need to be able to allocate large numbers of elements at a time but > then delete them one at a time. I have settled on the design of using > new[] to allocate many items at once, but am unsure what is legal/ > illegal about deallocation. Here's an example of what I would like to > do: > int *x = new int[1000]; > ... > delete x; > ... > delete x+1; > ... > delete x+2; > ... > ... > delete x+999; > Can I do this? Or do I have to delete the entire allocated array in > one chunk using delete[]? This example is not entirely accurate as I > would like the ordering of deletes to be more or less arbitrary. Any > help is greatly appreciated. Thanks, > -Chris > PS - If you want to know why I want this done - it's because I want to > save time allocating many objects instead of just one at a time and > I'll be passing pointers to these objects to many different functions > and places which will use them for awhile and then want to be able to > delete them.
Hello, Chris. You can't deallocate memory that you don't allocate. In other words, you can only deallocate memory using delete for the pointers you receive from new calls. If you need to dealocate one by one object, you will need to allocate one by one object: typedef int* PInt; PInt* px = new PInt[1000]; for( size_t i = 0; i < 1000; ++i ) px[i] = new int(); ... delete px[0]; ... delete px[1]; ... delete px[2]; ... ... delete px[999]; Now, if you can use STL instead pure and primitive arrays, we can use a list: std::list<int> x(1000); ... x.erase(myIterator); ... x.erase(myIterator2); ... ... x.erase(myIterator999); If I understood your target, and think the best method for what you looking for would be to use the placement new, i.e., creating all the objects you need inside a preallocated area of memory. After that, instead of deallocating the memory, you just need to call the destructor for the objects you need to dismiss. I assuming you using this technique with a real object, not primitive types. So: unsigned char myMem[sizeof(MyClass) * 1000); MyClass* pMyObjects = new (myMem) MyClass[1000]; ... pMyObjects[0].~MyClass(); ... pMyObjects[1].~MyClass(); ... pMyObjects[2].~MyClass(); ... ... pMyObjects[999].~MyClass(); []s Wanderley Caloni ====================== http://www.cthings.org
> If I understood your target, and think the best method for what you > looking for would be to use the placement new, i.e., creating all the > objects you need inside a preallocated area of memory. After that, > instead of deallocating the memory, you just need to call the > destructor for the objects you need to dismiss. I assuming you using > this technique with a real object, not primitive types.
Yes, you are correct and this was my intuition - preallocating memory somehow. However I'm slightly confused by your suggestion to just call the destructor for objects I need to dismiss. I thought that calling the destructor does not actually free the memory associated with the object - my understanding is that delete gets transformed as such: delete obj; --> compiles to... if (obj != NULL) { obj->~Object(); operator delete(obj); }
So if the destructor doesn't free anything, then I have to explicitly free the preallocated memory array anyway - why waste time calling the destructor when I can just call delete[] for the entire array? The overall goal is to avoid an additional messy data structure that would have to keep track of all the new[]'s for preallocated memory, detect when all the objects were finished, and safely call delete[] for the preallocated memory. It looks as though C++ does not offer a way to avoid this unless what you're saying about the destructor actually frees the memory from the preallocated array.
> unsigned char myMem[sizeof(MyClass) * 1000); > MyClass* pMyObjects = new (myMem) MyClass[1000]; > ... > pMyObjects[0].~MyClass(); > ... > pMyObjects[1].~MyClass(); > ... > pMyObjects[2].~MyClass(); > ... > ... > pMyObjects[999].~MyClass(); > []s
On 2007-06-05 20:40, Chris Portka wrote:
> I need to be able to allocate large numbers of elements at a time but > then delete them one at a time. I have settled on the design of using > new[] to allocate many items at once, but am unsure what is legal/ > illegal about deallocation. Here's an example of what I would like to > do: > int *x = new int[1000]; > ... > delete x; > ... > delete x+1; > ... > delete x+2; > ... > ... > delete x+999; > Can I do this? Or do I have to delete the entire allocated array in > one chunk using delete[]? This example is not entirely accurate as I > would like the ordering of deletes to be more or less arbitrary. Any > help is greatly appreciated. Thanks, > -Chris > PS - If you want to know why I want this done - it's because I want to > save time allocating many objects instead of just one at a time and > I'll be passing pointers to these objects to many different functions > and places which will use them for awhile and then want to be able to > delete them.
Is there any special reason why you can't wait and deallocate them all at once? Even if you could deallocate using delete what you allocated with new[] you would probably not be able to reallocate in the same area of memory until all of them had been deallocated so I can't see any gain from not deallocating them all at once. -- Erik Wikstrm
On Jun 5, 4:49 pm, Chris Portka <chrispor@gmail.com> wrote: > Yes, you are correct and this was my intuition - preallocating memory > somehow. However I'm slightly confused by your suggestion to just > call the destructor for objects I need to dismiss. I thought that > calling the destructor does not actually free the memory associated > with the object - my understanding is that delete gets transformed as > such: > delete obj; --> compiles to... > if (obj != NULL) { > obj->~Object(); > operator delete(obj);}
Quite right. My suggestion is explained by the fact that I thought your main concern was related with the destruction of objects, not the memory management. In this case, the deallocation would only take place at the end of use of all elements inside the collection, but you would be able to destruct any objects inside this array. > So if the destructor doesn't free anything, then I have to explicitly > free the preallocated memory array anyway - why waste time calling the > destructor when I can just call delete[] for the entire array? The > overall goal is to avoid an additional messy data structure that would > have to keep track of all the new[]'s for preallocated memory, detect > when all the objects were finished, and safely call delete[] for the > preallocated memory. It looks as though C++ does not offer a way to > avoid this unless what you're saying about the destructor actually > frees the memory from the preallocated array.
Now, back to the memory problem, I recommend the use of STL list class, if you want a collection of structures and don't want to worry about how to manage the deallocation of each element inside it, and these elements can be deallocated in a random way. []s Wanderley Caloni ====================== http://www.cthings.org
> Is there any special reason why you can't wait and deallocate them all > at once? Even if you could deallocate using delete what you allocated > with new[] you would probably not be able to reallocate in the same area > of memory until all of them had been deallocated so I can't see any gain > from not deallocating them all at once.
Yes there is a special reason, as I mentioned in my second comment - if I were to delete them all at once, this would require knowing when it was safe to delete them all. In order to know this I would have to keep around another data structure that kept track of which objects were finished and once it detected they were all finished, I could delete them. I'm trying to avoid using any additional data structures. -Chris
On Jun 5, 1:35 pm, Chris Portka <chrispor@gmail.com> wrote: > > Is there any special reason why you can't wait and deallocate them all > > at once? Even if you could deallocate using delete what you allocated > > with new[] you would probably not be able to reallocate in the same area > > of memory until all of them had been deallocated so I can't see any gain > > from not deallocating them all at once. > Yes there is a special reason, as I mentioned in my second comment - > if I were to delete them all at once, this would require knowing when > it was safe to delete them all. In order to know this I would have to > keep around another data structure that kept track of which objects > were finished and once it detected they were all finished, I could > delete them. I'm trying to avoid using any additional data > structures. > -Chris
You may want to consider using vectors to store the pointers.
On 5 Jun., 22:35, Chris Portka <chrispor@gmail.com> wrote: > > Is there any special reason why you can't wait and deallocate them all > > at once? Even if you could deallocate using delete what you allocated > > with new[] you would probably not be able to reallocate in the same area > > of memory until all of them had been deallocated so I can't see any gain > > from not deallocating them all at once. > Yes there is a special reason, as I mentioned in my second comment - > if I were to delete them all at once, this would require knowing when > it was safe to delete them all. In order to know this I would have to > keep around another data structure that kept track of which objects > were finished and once it detected they were all finished, I could > delete them. I'm trying to avoid using any additional data > structures. > -Chris
When you allocate something with new[], it results in ONE big chunk of memory. You can't deallocate a part of this chunk, only the full chunk. If you allocate the same amount of objects with several new (no []!) calls, it results in multiply memory chunks, which can be deleted separately. If it is your target to safe the allocation/deallocation time, use a memory pooling library (for example boost::pool). If it is your target to safe memory, use a std::list, as already suggested before.
|
 |
 |
 |
 |
|