Nick Gotch
Nick Gotch

Reputation: 9407

Issue passing C-Strings in C++

I'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();
}

Upvotes: 2

Views: 268

Answers (6)

HighCommander4
HighCommander4

Reputation: 52739

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.

Upvotes: 2

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361412

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

Upvotes: 1

Ekkehard.Horner
Ekkehard.Horner

Reputation: 38745

Because bar lives on tinker's stack; after leaving the function, its c_str() is gone.

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490118

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

Upvotes: 4

ggambetta
ggambetta

Reputation: 3433

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.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564413

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.

Upvotes: 8

Related Questions