From: Richard on
[Please do not mail me a copy of your followup]

Ulrich Eckhardt <eckhardt(a)satorlaser.com> spake the secret code
<07f7b7-sc.ln1(a)satorlaser.homedns.org> thusly:

>> You don't need to override operator new/delete.
>>
>> Do the simplest thing that could possibly work. Overriding operator
>> new/delete is more complicated than is necessary.
>
>Maybe that _is_ the simplest thing possible.

Maybe, but in this case: no, its not.

Even a simple smart pointer wrapper around this C data structure is
simpler for people to understand and maintain than overriding
new/delete.

Overriding new/delete is *hard* to do properly. It should be avoided
unless absolutely required and in this case, it isn't.
--
"The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download
<http://legalizeadulthood.wordpress.com/the-direct3d-graphics-pipeline/>

Legalize Adulthood! <http://legalizeadulthood.wordpress.com>
From: Sousuke on
On May 3, 1:02 pm, "bob" <rob...(a)robert.org> wrote:
> Hi,
>
> I need to allocate a variable size struct using malloc() and then free it
> using free().  Is there a way I could wrap a pointer returned from malloc()
> in auto_ptr<>?  I've used auto_ptr<> with objects of struct/class but only
> when they were allocated using new() operator.  AFAIK, it is generally not
> safe to allocate with malloc() and then free with delete().
>
> Example:
>
> struct {
>   int x;
>   int y;
>   unsigned char data[1];
>
> } structA;
>
> structA* pa = (structA*) malloc(100);
>
> I'd like to wrap pa pointer in auto_ptr<> so I do not have to worry about
> freeing it when I leave a given block.
>
> I think I could do the following:
>
> unsigned char* p = new unsigned char[100];
> structA* pa = (structA*) p;
> _auto_ptr<unsigned char> ptrA(p);
> [...]
>
> Any thoughts?

Sorry to drop in late, but here's something no one suggested: use
shared_ptr, which supports custom deallocation. (auto_ptr implements
single-owner ownership, whereas shared_ptr implements shared
ownership, so I think shared_ptr can be used as a replacement for
auto_ptr if you want.)

#include <stdlib.h>
#include <memory>

using namespace std::tr1;

// Your C-compatible struct
struct PacketData
{
int x;
int y;
unsigned char data[1];
};

struct PacketDataDeleter
{
void operator()(PacketData* pd)
{
free(pd);
}
};

// Suppose this is the function that reads from the
// network and assembles a PacketData
PacketData* ReadPacketData();

// Example usage
void DoSomething()
{
shared_ptr<PacketData> pd(ReadPacketData(), PacketDataDeleter());

// use pd
}
From: Ulrich Eckhardt on
Sousuke wrote:
> struct PacketDataDeleter
> {
> void operator()(PacketData* pd)
> {
> free(pd);
> }
> };
[...]
> shared_ptr<PacketData> pd(ReadPacketData(), PacketDataDeleter());

Can't you pass "&free" as deleter to the constructor?

Anyway, replacing exclusive ownership with shared ownership can work, but
doesn't have to. What I often have is exclusive ownership of mutable data
and shared ownership of constant data. This works even in the context of
multiple threads and actually is a big help there. Having shared mutable
data would mandate having a mutex for it, which complicates things.

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
From: Sousuke on
On May 18, 2:01 am, Ulrich Eckhardt <eckha...(a)satorlaser.com> wrote:
> Sousuke wrote:
> > struct PacketDataDeleter
> > {
> >     void operator()(PacketData* pd)
> >     {
> >         free(pd);
> >     }
> > };
> [...]
> >     shared_ptr<PacketData> pd(ReadPacketData(), PacketDataDeleter());
>
> Can't you pass "&free" as deleter to the constructor?

Yes... The Boost documentation left me thinking of that parameter as a
function object, but you can indeed pass "free" directly.