Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > is "delete" needed?

Reply
Thread Tools

is "delete" needed?

 
 
R.Z.
Guest
Posts: n/a
 
      08-09-2005
i'm using a class from some api that is said to automatically call its
destructor when its out of scope and deallocate memory. i create instances
of this class using "new" operator. do i have to explicitly call delete on
these instances when i no longer need them?


 
Reply With Quote
 
 
 
 
Maxim Yegorushkin
Guest
Posts: n/a
 
      08-09-2005

R.Z. wrote:

[]

> i create instances
> of this class using "new" operator. do i have to explicitly call delete on
> these instances when i no longer need them?


Yes, you do. Or better, use a smart pointer such as std::auto_ptr that
calls delete for you.

 
Reply With Quote
 
 
 
 
Richard Herring
Guest
Posts: n/a
 
      08-09-2005
In message <dda1en$fk7$(E-Mail Removed)>, R.Z.
<(E-Mail Removed)> writes
>i'm using a class from some api that is said to automatically call its
>destructor when its out of scope and deallocate memory.


Is that really what the documentation says? When _any_ automatic object
goes out of scope its destructor is automatically called. OTOH objects
created with "new" are not automatic, and don't "go out of scope".

> i create instances
>of this class using "new" operator. do i have to explicitly call delete on
>these instances when i no longer need them?
>

Does the API provide some other means (e.g. a "release" function) for
telling the instances they are no longer needed? APIs for
reference-counted objects commonly provide functions called something
like AddRef, which increases the reference count, and Release, which
decrements it and executes "delete this" if it becomes zero. If that's
the case, you must not use delete, as Release() does it for you. But
such objects are necessarily created on the heap, so the concept of
"going out of scope" doesn't really apply.

Or are they talking about some kind of smart pointer, such that the
pointer's destructor deletes the object when the pointer goes out of
scope?

--
Richard Herring
 
Reply With Quote
 
R.Z.
Guest
Posts: n/a
 
      08-09-2005
this class is a template intelligent array class. here's what the docs say:
Tabs may be used on the stack, i.e. they may be declared as a local variable
of a function or method. You can set the number of elements in the table,
work with them, and then when the function returns, the destructor of the
Tab is called, and the memory will be deallocated.

Tabs are only appropriate for use with classes that don't allocate memory.
For example, Tab<float> is fine while Tab<TSTR> is problematic (TSTR is the
class used for strings in 3ds max). In this case, the TSTR class itself
allocates memory for the string. It relies on its constructor or destructor
to allocate and free the memory. The problem is the Tab class will not call
the constructors and destructors for all the items in the table, nor will it
call the copy operator. As an example of this, when you assign a string to
another string, the TSTR class does not just copy the pointer to the string
buffer (which would result in two items pointing to the same block of
memory). Rather it will allocate new memory and copy the contents of the
source buffer. In this way you have two individual pointers pointing at two
individual buffers. When each of the TSTR destructors is called it will free
each piece of memory. So, the problem with using a Tab<TSTR> is that when
you assign a Tab to another Tab, the Tab copy constructor will copy all the
elements in the table, but it will not call the copy operator on the
individual elements. Thus, if you had a Tab<TSTR> and you assigned it to
another Tab<TSTR>, you'd have two TSTRs pointing to the same memory. Then
when the second one gets deleted it will be trying to double free that
memory.

So again, you should only put things in a Tab that don't allocate and
deallocate memory in their destructors. Thus, this class should not be used
with classes that implement an assignment operator and or destructor because
neither are guaranteed to be called. The way around this is to use a table
of pointers to the items.


 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      08-09-2005
In message <dda549$9lq$(E-Mail Removed)>, R.Z.
<(E-Mail Removed)> writes
>this class is a template intelligent array class. here's what the docs say:
>Tabs may be used on the stack, i.e. they may be declared as a local variable
>of a function or method. You can set the number of elements in the table,
>work with them, and then when the function returns, the destructor of the
>Tab is called, and the memory will be deallocated.


So far, so good. Normal behaviour for a container (it sounds a bit like
std::vector.) If you allocate a Tab with "new" (though I can't see why
you'd want to) then it's your responsibility to delete it when you've
finished with it.
>
>Tabs are only appropriate for use with classes that don't allocate memory.
>For example, Tab<float> is fine while Tab<TSTR> is problematic (TSTR is the
>class used for strings in 3ds max). In this case, the TSTR class itself
>allocates memory for the string. It relies on its constructor or destructor
>to allocate and free the memory. The problem is the Tab class will not call
>the constructors and destructors for all the items in the table, nor will it
>call the copy operator.


Not so good. It's like std::vector, but *worse*, because you can only
use it on PODs. Internally it's doing something like memcpy instead of
calling the contained class's copy constructor or assignment operator.

> As an example of this, when you assign a string to
>another string, the TSTR class does not just copy the pointer to the string
>buffer (which would result in two items pointing to the same block of
>memory). Rather it will allocate new memory and copy the contents of the
>source buffer. In this way you have two individual pointers pointing at two
>individual buffers. When each of the TSTR destructors is called it will free
>each piece of memory.


So the TSTR is a string-like class, with normal deep-copy semantics. But
because of the deep copy you can't store it in a Tab.

>So, the problem with using a Tab<TSTR> is that when
>you assign a Tab to another Tab, the Tab copy constructor will copy all the
>elements in the table, but it will not call the copy operator on the
>individual elements. Thus, if you had a Tab<TSTR> and you assigned it to
>another Tab<TSTR>, you'd have two TSTRs pointing to the same memory. Then
>when the second one gets deleted it will be trying to double free that
>memory.
>
>So again, you should only put things in a Tab that don't allocate and
>deallocate memory in their destructors. Thus, this class should not be used
>with classes that implement an assignment operator and or destructor because
>neither are guaranteed to be called. The way around this is to use a table
>of pointers to the items.
>

Presumably Tab provides something you haven't described, that makes it
more than just being a container, or you'd be better off using
std::vector. Unlike Tab, it provides an intelligent array which clears
up after itself *and* can be used on any class with normal copy
semantics, deep or shallow.

--
Richard Herring
 
Reply With Quote
 
ravinderthakur@gmail.com
Guest
Posts: n/a
 
      08-09-2005
hi r.z,

as clearly mentioned in the above documentation, use this Tab class
only for the object data types and not for pointer datatypes.

A Tab class object releases the resources allocated with the Tab object
itself and DOES NOT releases the resources pointed by the pointers
stored in it.

If you still want to store the pointers to the objects you have to
manually call destructor on the pointers stored in the Tab class by
iterating over the Tab class object. But even then u have to take care
when u are assigning one tab object to another one.


thanks,
rt

 
Reply With Quote
 
aslanski2002@yahoo.com
Guest
Posts: n/a
 
      08-11-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) yazdi:
> hi r.z,
>
> as clearly mentioned in the above documentation, use this Tab class
> only for the object data types and not for pointer datatypes.
>
> A Tab class object releases the resources allocated with the Tab object
> itself and DOES NOT releases the resources pointed by the pointers
> stored in it.
>
> If you still want to store the pointers to the objects you have to
> manually call destructor on the pointers stored in the Tab class by
> iterating over the Tab class object. But even then u have to take care
> when u are assigning one tab object to another one.
>
>


I had to do something like this. Here is a trick:

Wrap the pointer with a non-destructive class
template <class Ptr>
class NDPtr
{
Ptr* p;
public:
template <class Ptr> NDPtr(const Ptr* p_=0) {p=p_;}
template <class Ptr> NDPtr(const Ptr& r) {p=r.p;}
template <class Ptr> void operator=(const Ptr& r) {p=r.p;}
template <class Ptr> ~NDPtr() {/*NOTHING, See Below*/}
....
};

Then make a destructive class which has nothing but a destructor that
deletes the wrapped pointer.
template <class Ptr>
class DPtr : public NDPtr<Ptr>
{
public:
template <class Ptr> ~DPtr() { if(p) delete p;}
}

NDPtr<Type> can be used with Tab class or with any container class.
For example
set<NDPtr<char> > objCharPtrSet;

// use it as long as you want

And when you want to delete all the pointers do this:

// we should treat NDPtr as DPtr
// to delete the wrapped pointer.
set<DPtr<char> >& r = (set<DPtr<char> >&) objCharPtrSet;

// call clear to delete all the pointers
r.clear();


> thanks,
> rt


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments