Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C++ Programming

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.

On Jun 5, 3:40 pm, Chris  Portka <chrispor@gmail.com> wrote:

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.

On 2007-06-05 20:40, Chris Portka 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.

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

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc