This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: void pointer and map (fwd)
- From: Ted Byers <r dot ted dot byers at rogers dot com>
- To: Anitha Boyapati <anithab at sankhya dot com>, Andrew Haley <aph at redhat dot com>
- Cc: gcc-help at gcc dot gnu dot org
- Date: Fri, 21 Dec 2007 08:58:37 -0500 (EST)
- Subject: Re: void pointer and map (fwd)
--- Anitha Boyapati <anithab@sankhya.com> wrote:
>
> Hi,
>
> On Fri, 21 Dec 2007, Andrew Haley wrote:
>
> > Anitha Boyapati writes:
> > >
> > You're passing an instance of Value to
> Map::value_type, which creates
> > a pair instance by copying both the key and the
> value. Note that we
> > now have two instances of Value, both of which are
> pointing to the
> > same buf. operator delete will be called on both
> of these instances.
>
> Right! I missed a copy constructor then. That solves
> it then. Thanks.
>
That is a simple way to look at it, but perhaps too
simple.
You have to bear in mind the semantics maps require of
objects contained in them. Here is what you wrote:
struct Value {
int id;
void *buf;
Value (long l) { id = 4; buf = operator new(128);
long *c = reinterpret_cast<long *>(buf);
*c = l;
}
~Value() { operator delete(buf); }
};
bool operator< (const Value &v1, const Value &v2) {
bool result = (*(reinterpret_cast<long *>(v1.buf))) <
(*(reinterpret_cast<long *>(v2.buf)));
return result;
}
bool operator== (const Value &v1, const Value &v2) {
bool result = (*(reinterpret_cast<long *>(v1.buf)))
==
(*(reinterpret_cast<long *>(v2.buf)));
return result;
}
typedef map<Value, string> Map;
First, I don't see the point of reinterpret cast here,
or even use of a void pointer. Unless this is a
really dumbed down example, you probably ought to
think about the types you'll be using for this.
Second, why use a naked pointer instead of a smart
pointer (such as that found in boost)? You can use
the latter wherever you'd be tempted to use a naked
pointer, and it becomes all the easier to avoid the
sort of problem you posted about. With a smart
pointer, you could even get rid of the destructor
without losing anything, unless you need to make it
virtual, should there be a chance another class could
be derived from Value, which has a need for a
non-trivial destructor.
HTH
Ted