Deallocating Individual Elements of an Array Allocated Using new[]

C

Chris Portka

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.
 
A

Andre Kostur

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.
 
W

Wanderley Caloni

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 = 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
 
C

Chris Portka

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
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

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.
 
W

Wanderley Caloni

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
 
C

Chris Portka

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
 
N

Naresh Rautela

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.
 
A

Alexander Block

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,830
Latest member
HeleneMull

Latest Threads

Top