Free allocated memory

S

Sandy

I'm dynamically allocating memory to a variable in a function,
assigning some value to it and then returning this variable to the
caller. Where exactly should I free the memory allocated to this
variable. Will that happend automatically since the variable in
declared within the function scope?
 
H

Howard

Sandy said:
I'm dynamically allocating memory to a variable in a function,
assigning some value to it and then returning this variable to the
caller. Where exactly should I free the memory allocated to this
variable. Will that happend automatically since the variable in
declared within the function scope?

I'm _assuming_ that the variable you're talking about is a pointer.
Correct? If so, then no, it's not going to be freed for you. (And if it
did, you'd be returning an invalid pointer, wouldn't you?)

It's not usually a good idea to allocate memory in a function and then
return a pointer, because it may not be apparent to users of the function
that they need to free that memory themselves.

It's often better to allocate memory yourself, then call a function to fill
it for you (passing the object via a pointer or reference to it). (A member
function would even be better!) That way, you know you're in charge of the
allocated memory.

Or, you could create a constructor for the object which takes whatever
information you need and initializes the state of the object accordingly,
just as your function is now doing.

(And of course, there's always "smart" pointers; a whole 'nother subject!)

-Howard
 
D

Daniel T.

"Sandy said:
I'm dynamically allocating memory to a variable in a function,
assigning some value to it and then returning this variable to the
caller. Where exactly should I free the memory allocated to this
variable. Will that happend automatically since the variable in
declared within the function scope?

The memory will not be automatically reclaimed. The last code to use the
memory should free it.
 
M

mlimber

Howard said:
I'm _assuming_ that the variable you're talking about is a pointer.
Correct? If so, then no, it's not going to be freed for you. (And if it
did, you'd be returning an invalid pointer, wouldn't you?)

It's not usually a good idea to allocate memory in a function and then
return a pointer, because it may not be apparent to users of the function
that they need to free that memory themselves.

It's often better to allocate memory yourself, then call a function to fill
it for you (passing the object via a pointer or reference to it). (A member
function would even be better!) That way, you know you're in charge of the
allocated memory.

Or, you could create a constructor for the object which takes whatever
information you need and initializes the state of the object accordingly,
just as your function is now doing.

(And of course, there's always "smart" pointers; a whole 'nother subject!)

Returning dynamically allocated objects from a function is a common and
useful thing since it doesn't place as much of a burden on the user,
and smart pointers are the best way to handle it. For instance, a
factory function is a common need, and auto_ptr clearly communicates
that the client is required to clean-up the memory returned from the
function. E.g.,

#include <memory>
class A { /*...*/ };
std::auto_ptr<A> CreateA( /* any params to A's constructor */ )
{
// ...
return std::auto_ptr<A>( new A( /* those same params */ ) );
}

Now anyone who calls CreateA() is forced (ok, *strongly* encouraged) to
handle memory deallocation of the returned object.

Cheers! --M
 
R

Roland Pibinger

Yep!

Returning dynamically allocated objects from a function is a common and
useful thing

In Java yes, but not in C++.
since it doesn't place as much of a burden on the user,
and smart pointers are the best way to handle it. For instance, a
factory function is a common need, and auto_ptr clearly communicates
that the client is required to clean-up the memory returned from the
function. E.g.,

The purpose of auto_ptr is that the client is _not_ "required to
clean-up the memory".
Apart from that I agree with Howard's position. There are two secrets
of resource management:
1. don't return a resource (not even as "smart" pointer);
2. release resources in the destructor (if not done before) of a
containing object (and allocate the resources in a member function of
that object).

Best wishes,
Roland Pibinger
 
M

mlimber

Roland said:

Why do by hand what the standard library does for you? It's more
fragile and error prone. (Sure, auto_ptr has some pitfalls, but
Boost/TR1's complementary points improve the situation considerably.)
RAII is a powerful and useful technique. Why ignore it?
In Java yes, but not in C++.

Are you kidding me? Factory functions are a common design pattern. See
guru Sutter's example under "sources and sinks" here:

http://www.gotw.ca/publications/using_auto_ptr_effectively.htm

And see the virtual constructor idiom in the FAQ:

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8

You may not personally take advantage of them, but they're out there in
plenty of solid code. (And rightly so.)
The purpose of auto_ptr is that the client is _not_ "required to
clean-up the memory".

While you're right that auto_ptr will automatically delete its pointee
when it goes out of scope either by a normal change of scope or by an
exception (thus freeing the user from remembering/being able to do it),
I was here talking about using auto_ptr primarily to *transfer
ownership* from a factory function that creates an object to a client
who uses it and is responsible for deleting it (i.e., the factory does
not intend to clean it up). The client can delete it either by letting
an auto_ptr handle it, by taking over management by explicitly
releasing the object from the auto_ptr, or by transferring ownership
again to some other object (e.g., another smart pointer) that is
responsible for deleting it (either explicitly or implicitly via RAII).
Apart from that I agree with Howard's position. There are two secrets
of resource management:
1. don't return a resource (not even as "smart" pointer);

That's your rule, not generally accepted C++ wisdom.
2. release resources in the destructor (if not done before) of a
containing object

That's RAII, and it's the same technique auto_ptr uses.
(and allocate the resources in a member function of that object).

That's unnecessary. See "sinks" in the Sutter article mentioned above.

Cheers! --M
 
M

mlimber

mlimber said:
Are you kidding me? Factory functions are a common design pattern. See
guru Sutter's example under "sources and sinks" here:

http://www.gotw.ca/publications/using_auto_ptr_effectively.htm

And see the virtual constructor idiom in the FAQ:

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8

You may not personally take advantage of them, but they're out there in
plenty of solid code. (And rightly so.)

PS, Other C++ gurus also freely use factory functions and virtual
constructors. For instance, Scott Meyers does in _Effective C++_, Item
34; Sutter and Alexandrescu do in _C++ Coding Standards_ Item 49; and
the Creator himself does here:

http://www.research.att.com/~bs/bs_faq2.html#virtual-ctor

You are free to hold whatever opinion you want of such techniques, but
I think the general consensus of the most knowledgeable people is
weighted entirely against you.

Cheers! --M
 
R

Roland Pibinger

Are you kidding me? Factory functions are a common design pattern. See
guru Sutter's example under "sources and sinks" here:

http://www.gotw.ca/publications/using_auto_ptr_effectively.htm

"Avoid using auto_ptr, instead use shared_ptr"
(http://www.gotw.ca/publications/). Things change when you take a
closer look at smart pointers ...

Circle* Circle::clone() const { return new Circle(*this); }

Returns the ownership of a resource to the caller, an anti-idiom.
That's your rule, not generally accepted C++ wisdom.

A rule that mostly eliminates the troubles with resource management.
That's RAII, and it's the same technique auto_ptr uses.

There is a difference which can be described as deterministic vs.
non-deterministic resource management. The destruction of a returned
smart pointer like auto_ptr is non-deterministic.
That's unnecessary.

It 'only' encapsulates allocation and deallocation of resources, ie.
resource management.

Best wishes,
Roland Pibinger
 
R

Roland Pibinger

PS, Other C++ gurus also freely use factory functions and virtual
constructors. For instance, Scott Meyers does in _Effective C++_, Item
34; Sutter and Alexandrescu do in _C++ Coding Standards_ Item 49; and
the Creator himself does here:

http://www.research.att.com/~bs/bs_faq2.html#virtual-ctor

Your Stroustrup against my Stroustrup :)

"The name of the game here is to get allocation out of the way so you
don't see it. If you don't directly allocate something, you don't
directly deallocate it, because whoever owns it deals with it. ... As
you apply this technique recursively and in as many places as you can,
allocation and deallocation disappear from the surface level of your
code." http://www.artima.com/intv/modern3.html

IMO, the crucial point here is that the user is relieved of both,
"allocation and deallocation", resource management in general.

Best wishes,
Roland Pibinger
 
M

mlimber

Roland said:
Your Stroustrup against my Stroustrup :)

"The name of the game here is to get allocation out of the way so you
don't see it. If you don't directly allocate something, you don't
directly deallocate it, because whoever owns it deals with it. ... As
you apply this technique recursively and in as many places as you can,
allocation and deallocation disappear from the surface level of your
code." http://www.artima.com/intv/modern3.html

IMO, the crucial point here is that the user is relieved of both,
"allocation and deallocation", resource management in general.

Using a factory function follows the same principle ("If you don't
directly allocate something, you don't directly deallocate it, because
whoever owns it deals with it.") *if* one uses a smart pointer such as
std::auto_ptr since creation is hidden in the factory function (i.e.,
it is indirect) and the smart pointer owns the resource and will
destroy it (i.e., destruction is indirect).

The FAQ I mentioned technically violates this principle, but Stroustrup
clearly knows well the benefits of RAII and likely omitted the use of a
smart pointer for brevity's sake (i.e., that wasn't the point of that
example). See this FAQ which uses a factory function returning an
std::auto_ptr where it *is* the point of the example:

http://www.research.att.com/~bs/bs_faq2.html#memory-leaks

In short, your Stroustrup does not contradict my Stroustrup, and indeed
the C++ gurus' consensus is still entirely against you.

Cheers! --M
 
M

mlimber

Roland said:
"Avoid using auto_ptr, instead use shared_ptr"
(http://www.gotw.ca/publications/). Things change when you take a
closer look at smart pointers ...

Take a look at the history of the standard library's smart pointers
here:

http://boost.org/libs/smart_ptr/smart_ptr.htm#History

Originally, counted_ptr and auto_ptr (which had the semantics of
shared_ptr and scoped_ptr, respectively) were proposed for inclusion in
the library, but the Library Working Group's recommendation was
over-ruled, counted_ptr was dropped and the copy semantics for auto_ptr
were changed (most think for the worst). Sutter is merely advocating
the original approach, which experience has shown is generally better.
Circle* Circle::clone() const { return new Circle(*this); }

Returns the ownership of a resource to the caller, an anti-idiom.

I would certainly return a smart pointer rather than a bald pointer,
but that is not the point of the example. (Compare Stroustrup's FAQs on
memory leaks and virtual constructors.)
A rule that mostly eliminates the troubles with resource management.

Again, the advice of the C++ gurus is entirely against you.
There is a difference which can be described as deterministic vs.
non-deterministic resource management. The destruction of a returned
smart pointer like auto_ptr is non-deterministic.

I don't follow you here.
It 'only' encapsulates allocation and deallocation of resources, ie.
resource management.

Don't misunderstand me. It's a good principle to encapsulate
construction and destruction in a class when possible (that's what
containers like std::vector do, after all), but it is not always
possible, e.g., when you're using an object polymorphically and the
concrete type of the object is not known until run-time. That's a
common place to use a factory function, as mentioned above.

Cheers! --M
 
R

Roland Pibinger

Roland Pibinger wrote:
The FAQ I mentioned technically violates this principle, but Stroustrup
clearly knows well the benefits of RAII and likely omitted the use of a
smart pointer for brevity's sake (i.e., that wasn't the point of that
example). See this FAQ which uses a factory function returning an
std::auto_ptr where it *is* the point of the example:
http://www.research.att.com/~bs/bs_faq2.html#memory-leaks
In short, your Stroustrup does not contradict my Stroustrup, and indeed
the C++ gurus' consensus is still entirely against you.

Stroustrup: "Smart pointers are popular, but should be approached with
care. They are not the panacea that they are sometimes presented to
be." http://www.research.att.com/~bs/DnE2005.pdf

Regards,
Roland Pibinger
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top