Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Returning local variable

7 views
Skip to first unread message

Minkoo Seo

unread,
Jul 25, 2006, 7:20:31 AM7/25/06
to
Hi list.

Could you please take a look at the following code?

#include <iostream>

using namespace std;

const char *foo()
{
string f = "fo";
f += "o";
return f.c_str();
}

int main()
{

cout << foo() << endl; // I need const char * here!!!
return EXIT_SUCCESS;
}

f is a local variable of foo which will be destroyed after foo( ) is
completed. I'm not sure where I've read this, but I think I've read
that returning const char * that points to a local variable is safe
while just returning char * of local variable is an error. That being
the case, the above code is safe. So I wonder, does const really
related to returning a local variable?

If returning const char * is not safe, then how would you correct the
above code? Will you use auto_ptr? or use new in this function and
delete in other function?

Sincerely,
Minkoo Seo


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Ulrich Eckhardt

unread,
Jul 25, 2006, 9:54:09 AM7/25/06
to
Minkoo Seo wrote:
> > #include <iostream>
> >
> > using namespace std;
> >
> > const char *foo()
> > {
> > string f = "fo";
> > f += "o";
> > return f.c_str();
> > }

This returns a pointer to private storage of the local variable 'f'.
However, 'f' will be destroyed when the function returns and the pointer
be left pointing to nowhere, invoking undefined behaviour.

> > cout << foo() << endl; // I need const char * here!!!

Huh? What makes you think so? Of course you can write a std::string
(whos header you didn't include, btw) to a std::ostream like std::cout.
BTW: to be really standard conformant, you also need <ostream> to get
the definitions of std::ostream and its associated operators.

If you had a problem with the original code, say that instead of
resorting to workarounds that don't work - I guess that was the case here.

Uli

Alf P. Steinbach

unread,
Jul 25, 2006, 9:50:41 AM7/25/06
to
* Minkoo Seo:

> >
> > #include <iostream>
> >
> > using namespace std;
> >
> > const char *foo()
> > {
> > string f = "fo";
> > f += "o";
> > return f.c_str();

Don't.

> > }
> >
> > int main()
> > {
> >
> > cout << foo() << endl; // I need const char * here!!!

Undefined Behavior, because the pointer you receive from foo() points to
memory that's already been deallocated.


> > return EXIT_SUCCESS;
> > }
> >
> > f is a local variable of foo which will be destroyed after foo( ) is
> > completed. I'm not sure where I've read this, but I think I've read
> > that returning const char * that points to a local variable is safe

No, that's incorrect.


> > while just returning char * of local variable is an error.

Not sure what that's supposed to mean, "of" as opposed to "points to".


> > That being
> > the case, the above code is safe. So I wonder, does const really
> > related to returning a local variable?

No.


> > If returning const char * is not safe, then how would you correct the
> > above code? Will you use auto_ptr? or use new in this function and
> > delete in other function?

Use std::string. :-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Vladimir Ciobanu

unread,
Jul 25, 2006, 9:53:10 AM7/25/06
to

> > const char *foo()
> > {
> > string f = "fo";

std::string::string(const char*) is called, which initializes the
string 'f' with the requested value.

> > f += "o";

Play a bit with the string.

> > return f.c_str();

Wrong. Consider an extremely simplified implementation of std::string

class string {
const char* data_;
public:
// ...
const char* c_str() const { return data_; }
~string() { delete[] data_; }
};

So, what happens here is: f.c_str() is evaluated, which returns a const
char pointer, as expected. The return statement returns that pointer.
However, as soon as it's done with the return, the stack unwinding
process starts, and the local 'f' variable's dtor is called, which
invalidates the pointer.

> > cout << foo() << endl; // I need const char * here!!!

Error, undefined behaviour. The pointer has been deleted.


A solution to this problem is using static variables (ie. declaring f
as static). This means its ctor is called once, when the function is
first called and its dtor, only once, on program exit. Note that
calling the function the second time will return "fooo", rather than
the same "foo" result.

Another solution is using a reference counte smartpointer to hold your
'f' string object. Check boost for a very good implementation as well
as good docs on it.

Francis Glassborow

unread,
Jul 25, 2006, 9:58:34 AM7/25/06
to
In article <1153808157.6...@h48g2000cwc.googlegroups.com>,
Minkoo Seo <minko...@gmail.com> writes

> >If returning const char * is not safe, then how would you correct the
> >above code? Will you use auto_ptr? or use new in this function and
> >delete in other function?
Returning a pointer derived from any non-static local variable is always
a 'no-no'.

In this case it is compounded because c_str() is strictly constrained
and cannot even be used if any non-const std::stirng has been called on
the original.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects

Victor Bazarov

unread,
Jul 25, 2006, 9:57:37 AM7/25/06
to
Minkoo Seo wrote:
> > Could you please take a look at the following code?
> >
> > #include <iostream>
> >
> > using namespace std;
> >
> > const char *foo()
> > {
> > string f = "fo";
> > f += "o";
> > return f.c_str();
> > }
> >
> > int main()
> > {
> >
> > cout << foo() << endl; // I need const char * here!!!
> > return EXIT_SUCCESS;
> > }
> >
> > f is a local variable of foo which will be destroyed after foo( ) is
> > completed. I'm not sure where I've read this, but I think I've read
> > that returning const char * that points to a local variable is safe
> > while just returning char * of local variable is an error. That being
> > the case,

It's not.

> > the above code is safe.

It isn't.

> > So I wonder, does const really
> > related to returning a local variable?

I don't understand the question, I guess.

> > If returning const char * is not safe, then how would you correct the
> > above code?

Rewrite the interface to return a string. Or return a pointer to
an array allocated in free store. As a last resort, make 'f' static.

> > Will you use auto_ptr?

No.

> > or use new in this function and
> > delete in other function?

Possibly.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Frederick Gotham

unread,
Jul 25, 2006, 10:39:11 AM7/25/06
to
Minkoo Seo posted:

> const char *foo()
> {
> string f = "fo";
> f += "o";
> return f.c_str();
> }


std::string Func()
{
std::string f = "fo";

f += "o";

return f;
}

--

Frederick Gotham

0 new messages