I开发者_StackOverflow中文版'm not C++ developer and I'm trying to figure out why when I return a C-string from a function I'm getting garbage out.
#include <stdio.h>
const char* tinker(const char* foo);
int main(void)
{
const char* foo = "foo";
foo= tinker(foo);
printf(foo); // Prints garbage
return 0;
}
const char* tinker(const char* foo)
{
std::string bar(foo);
printf(bar.c_str()); // Prints correctly
return bar.c_str();
}
You're returning a C-string that's based on the internal memory of a std::string
. However, this is being printed AFTER your bar
is destructed. This memory is garbage by the time it reaches the printf(foo);
line.
You're returning a pointer to a buffer internal to bar
, but then you're destroying bar
(and the buffer) before you use that pointer.
If you need the content of bar
after the function returns, return bar
instead of bar.c_str()
.
To add to what others said, this is one way to get it to work:
#include <stdio.h>
std::string tinker(const char* foo);
int main(void)
{
const char* foo = "foo";
std::string foo2= tinker(foo);
printf(foo2.c_str()); // Prints correctly
return 0;
}
std::string tinker(const char* foo)
{
std::string bar(foo);
return bar;
}
Here the std::string object is copied* through the return value and you are printing the copy in main().
*popular string implementations employ optimizations like reference counting that avoid actually copying the string. In addition, in C++0x the string object will be moved, not copied.
Because you're allocating bar in tinker's stack. When tinker ends, its stack is reclaimed, bar is deleted, so the pointer you're returning points to deallocated memory, ie it's not valid anymore when you exit the function.
Because bar lives on tinker's stack; after leaving the function, its c_str() is gone.
return bar.c_str();
This line returns the char*
of a temporary object, which gets deleted at the end of the function, and so in main() foo
points to the deleted object char*
.
精彩评论