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

Ulrich Eckhardt <eckhardt(a)satorlaser.com> spake the secret code
<94t4b7-94t.ln1(a)satorlaser.homedns.org> thusly:

>bob wrote:
>> 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<>?
>
>No, auto_ptr uses delete, which you must not use with a pointer returned
>from malloc. What I'm not sure about is whether you could override
>operators new/delete for your struct and redirect these accordingly to do
>The Right Thing(tm). I'd try asking this in comp.lang.c++.moderated.

Overriding operator new/delete for a struct is overkill. Just have
the c'tor and d'tor handle the resource acquisition and release just
like any other RAII helper.
--
"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: Ulrich Eckhardt on
Richard wrote:
> Ulrich Eckhardt <eckhardt(a)satorlaser.com> spake the secret code
> <94t4b7-94t.ln1(a)satorlaser.homedns.org> thusly:
>
>>bob wrote:
>>> 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<>?
>>
>>No, auto_ptr uses delete, which you must not use with a pointer returned
>>from malloc. What I'm not sure about is whether you could override
>>operators new/delete for your struct and redirect these accordingly to do
>>The Right Thing(tm). I'd try asking this in comp.lang.c++.moderated.
>
> Overriding operator new/delete for a struct is overkill. Just have
> the c'tor and d'tor handle the resource acquisition and release just
> like any other RAII helper.

No, read the original posting again: The OP wants to allocate a structure
with a _variable_ size. For that, you use an array as last struct member
(in his case one with size 1, but IIRC C99 also allows size zero now) and
allocate extra bytes at the end.

Uli

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

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
From: bob on
Thanks to everyone who replied to my post.

It looks like I have to get rid of malloc()/free() or forget about
auto_ptr<> and deal with deallocating memory manually.

For those interested, the reason that I'm using a variable length struct is
that I receive it from a network as a stream of bytes. The first couple of
bytes represent a header and the length of variable size data that follows.
I have a low-level c routine that deals with assembling the packet and then
returns it to clients. Currently the routine allocates ram for the packet
and the client frees it. Quite often logic on the client gets a bit
complicated and ideally I'd like to use auto_ptr<> so I do not need to worry
about freeing the memory allocated in the c routine.

Thanks.

"bob" <robert(a)robert.org> wrote in message
news:Oid8bru6KHA.3880(a)TK2MSFTNGP04.phx.gbl...
> 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?
>
> Thanks.
>


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

Ulrich Eckhardt <eckhardt(a)satorlaser.com> spake the secret code
<9pn5b7-fku.ln1(a)satorlaser.homedns.org> thusly:

>No, read the original posting again: The OP wants to allocate a structure
>with a _variable_ size.

Yeah, big deal. So its variable size. So its allocated by a C
library.

So what?

You can still handle the acquisition and release of this resource with
a c'tor/d'tor pair.

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.
--
"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: John H. on
bob wrote:
> Thanks to everyone who replied to my post.
>
> It looks like I have to get rid of malloc()/free() or forget about
> auto_ptr<> and deal with deallocating memory manually.
>
> For those interested, the reason that I'm using a variable length struct is
> that I receive it from a network as a stream of bytes. The first couple of
> bytes represent a header and the length of variable size data that follows.
> I have a low-level c routine that deals with assembling the packet and then
> returns it to clients. Currently the routine allocates ram for the packet
> and the client frees it. Quite often logic on the client gets a bit
> complicated and ideally I'd like to use auto_ptr<> so I do not need to worry
> about freeing the memory allocated in the c routine.

Is it a requirement that the low-level be C? One thing you might try
is redoing your struct like this:

struct structA {
int x;
int y;
std::vector<unsigned char> data;
};

You can then return this structure by value to the client code. When
they are done using it, the memory will clean itself up. If you don't
like to return by value, you could put the structA into an auto_ptr
and return that:

structA read_socket(socket & sock)
{
unsigned char buffer[256] = {0};
buffer << sock;
structA packet;
packet.data.insert(data.begin(), buffer, buffer+255);
return packet;
}

or

std::auto_ptr<structA> read_socket(socket & sock)
{
unsigned char buffer[256] = {0};
buffer << sock;
std::auto_ptr<structA> packet(new structA);
packet->data.insert(data.begin(), buffer, buffer+255);
return packet;
}

Also as Richard said, you could leverage a constructor/destructor into
the structA to simplify the interface even more.
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4
Prev: Reversing 2nd order deep std::vector
Next: Visual C++ 2010