From: bob on
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: John H. on
bob wrote:
> I need to allocate a variable size struct using malloc() and then free it
> using free().

Why? That seems atypical.

> Is there a way I could wrap a pointer returned from malloc()
> in auto_ptr<>?

Perhaps. See below.

> I've used auto_ptr<> with objects of struct/class but only
> when they were allocated using new() operator.

This is good. auto_ptr was designed to work with new and delete
(scalar versions).

> AFAIK, it is generally not
> safe to allocate with malloc() and then free with delete().

That is correct.

> Example:
>
> struct {
> int x;
> int y;
> unsigned char data[1];
> } structA;
>
> structA* pa = (structA*) malloc(100);

Whenever you fine yourself reaching for malloc in C++, you should
question whether that is really what you should be doing. It looks
like you are trying to treat your structure as something that has an
x, y, and then some data which is explicitly one char big, but really
might be more (perhaps 92 bytes in your case). Rather than doing
obscure things with memory, I think you are better of using a
different data structure. Consider making data an std::vector. That
way it can have a dynamic size, and the cleanup is done for you. You
don't have to worry about auto_ptr.

> 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.

Well in general that can be a fine goal, but in your situation I am
not sure.

> I think I could do the following:
>
> unsigned char* p = new unsigned char[100];
> structA* pa = (structA*) p;
> _auto_ptr<unsigned char> ptrA(p);
> [...]

So this is a different problem than the first one mentioned, where
you needed malloc and free? I guess you are trying to accomplish the
same thing with the data structure, but using new/delete instead.
Perhaps it is slightly better than the malloc/free version, but it
still seems to be missing the mark.

> Any thoughts?

I think you want to rethink things and I would need to know more about
what you are trying to do to give you good advice.
But if you really want to use auto_ptr with malloc/free you might
consider something like the following. I am not sure if it works
correctly or safely.

#include <memory>
#include <cstdlib>

struct structA
{
int x;
int y;
unsigned char data[1];
void operator delete(void * this_ptr);
private:
void * operator new(unsigned int);
};

void structA::operator delete(void * this_ptr)
{
std::cout << "delete" << std::endl;
free(this_ptr);
}

int main()
{
void * memory = malloc(100);
structA * fake_structA = static_cast<structA *>(memory);
std::auto_ptr<structA> autoptr(fake_structA);
return 0;
}
From: Richard on
[Please do not mail me a copy of your followup]

"bob" <robert(a)robert.org> spake the secret code
<Oid8bru6KHA.3880(a)TK2MSFTNGP04.phx.gbl> thusly:

>I need to allocate a variable size struct using malloc() and then free it
>using free(). [...]

There are better ways to do this in C++.

The only time you need to use malloc/free is when you are
interoperating with a C (not C++) library.

Personally, when I need to talk to C code, I hide it behind an
abstraction that handles all the interoperability concerns for me.

Part of that is using c'tors and d'tors that handle malloc/free business.
--
"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:
> I think I could do the following:
>
> unsigned char* p = new unsigned char[100];
> structA* pa = (structA*) p;
> _auto_ptr<unsigned char> ptrA(p);
> [...]

That might not work very well, as you allocated with new[] and
auto_ptr will deallocate with scalar delete.
From: Ulrich Eckhardt on
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.

> structA* pa = (structA*) malloc(100);

Use static_cast.

If everything fails, you can also write an auto_ptr-like class yourself. Or
take this one:

http://lists.boost.org/Archives/boost/2007/11/130127.php

Cheers!

Uli

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

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932