Re: Returning an unknown number of types/values

From: Jumbo (nospam)
Date: 01/14/04


Date: Wed, 14 Jan 2004 08:14:42 -0000


"Jacques Labuschagne" <jacques@clawshrimp.com> wrote in message
news:TJ5Nb.17143$ws.2033293@news02.tsnz.net...
> Jumbo
> > "Jacques Labuschagne" <jacques@clawshrimp.com> wrote in message
> > news:yJ3Nb.17128$ws.2031755@news02.tsnz.net...
> >
> >>Jumbo
> >>
> >>>I have a few points to make:
> >>>1) I had to remove the code you had inside the derived destructor to
get
> >
> > it
> >
> >>>to compile , as the base destructor deletes the memory allocated this
> >
> > seems
> >
> >>>to be ok.
> >>>I'm not sure what you were trying to do with that code.
> >>
> >>There are two steps. The first is calling the T's desctructor, and the
> >>second is freeing the memory. Because you're deleting an array of
> >>unsigned char, the object's destructor won't be called automatically.
> >>My derived destructor compiles on GCC 3.2.3; which compiler are you
> >>using?
> >
> > VSTUDIO.NET I'm using.
>
> I'm sure this works with VS.Net; I'll give it a try for myself.
>
> > Honestly I still don't know what you on about with this destructor
here's
> > the code you had in the derived destructor:
> > T* t = reinterpret_cast<T*>(buf_);
> > t.~T();
> >
> > You seem to declaring a new object here then asking to delete itself. or
> > smething I dunno what it does. But it honestly doesn't compile here. But
> > anyway why do we need it as when the derived object is destroyed if it's
> > destructor is empty the Base destructor will still clear up the memory
by
> > the deleting the memory that was allocated in the derived constructor.
So it
> > works fine with and empty derived destructor as far as I can see.
>
> Consider this example:
>
> class X{
> public:
> X(): iptr(new int[50]){}
> ~X(){ delete[] iptr; }
> int *iptr;
> };
>
> Derived<X> d;
>
> Consider what happens when 'd' is destroyed. If X's destructor is never
> executed, X::iptr will never be freed. When you say
> X* x = new X;
> delete X;
> What's actually happening at the delete step is
> call X::~X(),
> free (sizeof(X)) bytes at &X.
> Base's destructor says something subtly different; it says
> free N unsigned chars.

Well whatever object creates a new object should delete it when its finished
with it.

WHy is base different ? The only memory that you allocated was:
the array of unsigned chars[sizeof(T)]
This array was allocated to the unsigned char pointerin the Base class's
protected section.
Therefore the only object that needs freeing is this array which is pointed
to by the base classes variable.
When the derived class is destroyed it's destructed need to do nothing
control will jump to the base classes destructor which deletes the array of
unsigned characters that were previously allocated by the derived classes
constructor.

I don't see why is difficult about that.
1 Array is allocated and 1 Array is deleted. It simple.

> That won't free X::iptr, because the memory allocated to it isn't
> within X, it's somewhere else... X::iptr /points/ at that other
> location.
> It is perfectly legal to call the destructor of an object by hand,
> so in Derived's dtor we need to do the following:
> T* t = reinterpret_cast<T*>(buf_);
> That gives us a pointer to buf_. The useful thing about this pointer
> is that *it knows it's a T*. We can then call the destructor of
> the object that has been constructed in buf_, because we have a
> pointer to it.
> t.~T();
> We could also move the delete[] buf_ into the derived destructor if
> we like... If we do that, consider what we have then:
> t.~T();
> delete[] buf_;
> And those are exactly the two steps that have to be performed when
> an object is deleted. To reiterate, we need to manually destruct
> (not just free the memory to) the object we constructed in buf_
> because it is not the same type as an element of buf_.
>
> >
I still don't see what your talking about
Assume T= int.
in your derived destructor your code goes:
T* t = reinterpret_cast<T*>(buf);
t.~T();

The first line creates an int* right? So you have created a new pointer in
the destructor where your suppposed to be delting stuff.
the second line seems to be calling the destructor of an integer pointer and
it won't compile on my system. I didn't realsile that you could do that
I've never seen it before. If T is an int that code is like doing this:
int* pInt;
pInt.~int*();
I don't see what that is supposed to do at all.
You do realise that the operator ~ is also a bitwise operator ?

> >
> >
> > I did some more work and here is my lates code:
> > As you will see I changed the use of bytes to using void pointers and
sorted
> > out a few other things:
>
> The last remaining show-stopper is that one can't copy derived objects
> without leaking memory. You should at least support copying between
> two Derived<T> objects (who have the same type T).
Why can you not copy derived objects? You mean in general or are you talking
about your derived object? Yeah well copy constructors explicitness of
contructors overloading = operators and optimisation through template
specialization all comes under the same kinda category . I consider that
quite far along in terms og developmentr progress. I like to get my designed
sorted and working properly before I start to implement all that.
Everyone has a different way , some people always put in destructors and
stuff at the start whereas I leave them till nearer the end. If you want to
overload the subscript operators on multi-demension array types be sure you
check this early on as I you may have problems overloading the subscript
operator to the second dimentsion to return different types. As the function
will be templated you cannot make it virtual and overloaded functions cannot
only differ on return types so how do you index the array
int x = array[5][6];
char y = array[5][7];
where you created a multi data type array? ;-)
I don't think it's possible you need to use accessor function that is why
vectors use accessors instead of subscripts.

THe probelm appears when you try to overload the second subscript operator
as I explained above your function cannot differ only in return type, you
can get away with it on the first subscript operator as that does not need
to be virtual and therefore can be templated..
>
>
Another thing there are problems using strings and stuff aswell.
I think my original design was a bit better than this now.



Relevant Pages

  • Re: Returning an unknown number of types/values
    ... > Therefore the only object that needs freeing is this array which is pointed ... > to by the base classes variable. ... > in your derived destructor your code goes: ... So you have created a new pointer in ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Returning an unknown number of types/values
    ... the object's destructor won't be called automatically. ... > My derived destructor compiles on GCC 3.2.3; ... /* this basically constructs and controls the multi-type array, ... /* private function used to get the size of the contructors array parameter ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Using auto_ptr with array of doubles in VS6 and VS2005
    ... since it is undefined behavior to call delete on the above array ... Naturally basic types have no destructor, so not running it is not particularly a problem. ...
    (microsoft.public.vc.language)
  • Re: Why delete [] for aray?
    ... Does he use of delete instead of deletewill cause a memory leak? ... the pointer points to an array. ... Moreover, when allocating arrays of classes with non-trivial destructor, ...
    (microsoft.public.vc.language)
  • Re: is such exception handling approach good?
    ... No exception from this rule that I know of (no pun ... For the object pointed by smart pointer, ... Free that resource in the destructor. ... For resources other than the heap memory, you would use other classes to ...
    (microsoft.public.vc.language)

Loading