Board index » cppbuilder » Deleting TList Objects + Pointers

Deleting TList Objects + Pointers

Since TList stores a list of pointers, doesn't delete only delete the
pointer?  how do we delete the actual object?
ie:
TWidget *widget = new TWidget(this);
TList widgetList = new TList;
widgetList->Add(widget);
widgetList->Items[0]->Delete();  //gets rid of only pointer?
delete widget;  //gives problem (is it because of "this" owner

--
jtt

 

Re:Deleting TList Objects + Pointers


Quote
"jtt" <j...@nospam.com> wrote in message

news:3d826ae8@newsgroups.borland.com...

Quote
> Since TList stores a list of pointers, doesn't delete
> only delete the pointer?

Yes

Quote
> how do we delete the actual object?

You have to manually iterate through the list first first, deleting each
individual item.
    TList widgetList = new TList;
    widgetList->Add(new TWidget(this));

    for(int x = 0; x < widgetList->Count; x++)
        delete (TWidget*)widgetList->Items[x];
    delete widgetList;

Gambit

Re:Deleting TList Objects + Pointers


Quote
Remy Lebeau [TeamB] wrote:
>     TList widgetList = new TList;
>     widgetList->Add(new TWidget(this));

>     for(int x = 0; x < widgetList->Count; x++)
>         delete (TWidget*)widgetList->Items[x];
>     delete widgetList;

I'm really confused and am getting strange program termination hangups (ie
doesn't terminate) which I'm pretty sure is related to memory and
especially with TList of pointers.  Am I buggy, is BCB buggy or neither -
do I just need more clarification?

if the TWidget is a component descendant from TCustomControl and is given an
owner of "this" - doesn't the parent class automatically delete it?  and if
I try to delete it, I get bad results ?  this is confusing since the normal
C++ rule is wherever there is a "new" you better have a "delete"

so let's look at some different conditions and whether code is right?
1) TWidget *mywidget = new TWidget(this);
//do some stuff here
delete mywidget;  //correct? or does "this" owner delete it?

2) TList *mylist = new TList;
mylist->Add(new TWidget(this));
//do some stuff here
for (int i=0;i<mylist->Count;i++) {
    delete (TWidget *)mylist->Items[i];  //but if widget is owned by parent
does it need to be deleted ?  doing this seems to give problems

Quote
}

delete mylist;  //again does this need to be deleted or does owner delete? -
is there an implied owner with "new TList;" no parameters

//I've really had trouble with TPoint/Point
3) TPoint *anode = new TPoint(10,10);
  //do stuff here
  delete anode;  // this seems to give problems (again owner issue?)
4) TList *ptlist = new TList;
ptlist->Add(new TPoint(10,10);
//do stuff
for (int i=0;i<ptlist->Count;i++) {
    delete (TPoint *)ptlist->Items[i];  

Quote
}   //this seems to give problems

delete ptlist;
5)TList *ptlist = new TList;
TPoint *anode = new TPoint(10,10);
ptlist->Add(anode);
//do stuff
for (int i=0;i<ptlist->Count;i++) {
    delete (TPoint *)ptlist->Items[i];  
Quote
}   //this seems to give problems

delete ptlist;

appreciate any clarification.

--
jtt

Re:Deleting TList Objects + Pointers


Quote
"jtt" <j...@nospam.com> wrote in message

news:3d8539b6@newsgroups.borland.com...

Quote
> if the TWidget is a component descendant from
> TCustomControl and is given an owner of "this" -
> doesn't the parent class automatically delete it?

The Owner, not the Parent, does.  But yes, technically it is owned and as
such will be automatically freed for you.

Quote
> and if I try to delete it, I get bad results ?

No.  Manually deleting owned compoents is perfectly safe.  In the
component's inherited destructor, it will simply remove itself from its
Owner's internal list of owned components, so that the Owner won't try to
free the component a second time later on.

Quote
> this is confusing since the normal C++ rule is wherever
> there is a "new" you better have a "delete"

Under normal circumstances, yes.  However, the VCL is a special case,
because 1) it is Pascal-based, not C++-based, and 2) the VCL has the Owner
mechanism implemented to automatically handle some things that you would
otherwise need to handle yourself.

Quote
> 1) TWidget *mywidget = new TWidget(this);
> //do some stuff here
> delete mywidget;  //correct?

Technically, the code is correct, from a syntax point of view.
Functionality-wise, whether you call 'delete' yourself or not, the widget
will still be freed eventually one way or another.  Either by you
explitically, or by the Owner implicitally.

Quote
>     delete (TWidget *)mylist->Items[i];  //but if widget is
> owned by parent does it need to be deleted ? doing this
> seems to give problems

There's nothing wrong with freeing owned components yourself, as mentioned
above.

Quote
> delete mylist;  //again does this need to be deleted or does owner

delete? -

The TList itself has no Owner.  So yes, you must explitically 'delete' the
list yourself.

Quote
> is there an implied owner with "new TList;"

No.

Quote
> 3) TPoint *anode = new TPoint(10,10);
>   //do stuff here
>   delete anode;  // this seems to give problems (again owner issue?)

TPoint has no Owner, either.  Since you manually 'new' it, you have to
manually 'delete' it as well.

However, it should be noted that TPoint is a simple structure, not a class.
For the majority of the time that you use it, you really should be using it
on the stack, not the heap.  Thus, don't use 'new' and 'delete' with it.
Just declare it normally, and let the stack manage it for you:

    TPoint anode(10,10);
    //do stuff here

It will automatically be freed when it goes out of scope.

Quote
> 4) TList *ptlist = new TList;
> ptlist->Add(new TPoint(10,10);
> //do stuff
> for (int i=0;i<ptlist->Count;i++) {
>     delete (TPoint *)ptlist->Items[i];
> }   //this seems to give problems
> delete ptlist;

This, on the other hand, you do need to use 'new' and 'delete' to store the
TPoint on the heap, in order to ensure that each TPoint instance stays in
scope for the lifetime of the list (or at least until you remove them from
the list).

From both syntax and functionality levels, the above code is correct.

Quote
> 5)TList *ptlist = new TList;
> TPoint *anode = new TPoint(10,10);
> ptlist->Add(anode);
> //do stuff
> for (int i=0;i<ptlist->Count;i++) {
>     delete (TPoint *)ptlist->Items[i];
> }   //this seems to give problems
> delete ptlist;

Again, 'new' and 'delete' are needed for each instance, and your code is
correct.

Gambit

Re:Deleting TList Objects + Pointers


Quote
Remy Lebeau [TeamB] wrote:

Thks again Remy for your clear help, especially about TPoint - if you or any
other  authors are reading this, pls feel free to use these examples in a
chapter on memory management - some of us really need such a chapter ! A
good chapter title might be "Managing complex objects".
--
jtt

Other Threads