#include <iostream>
using namespace std;

const char* foo() {
    return "Hello";
}
const char* bar() {
    const char* s = "world";
    return s;
}

void print(const char* s) {
    cout << s << endl;
}

int main () {
    cout << foo() << endl;
    print(bar());
    return 0;
}

Can I return those strings in foo and bar functions that way? that I ask this question is because I think those char* pointers in foo and bar functions are temporaries, and when the function calls in main return, they are deallocated, and I think the program should crash, but it compiles and runs fine. I have asked a similar question in an IRC channel, they mentioned static storage duration, I have googled for quite a while and found little on this. So what is static storage duration?

Your help will be greatly appreciated!

Because both strings, in foo and bar, are string literals they 'may' be stored in the text section(or some read only section) and therefore may be permanent to the process.

Edited 5 Years Ago by gerard4143: n/a

This will work, because the hard coded strings are stored in the strings section of your executable, and s just points to that. After the function returns the string will still be there.

static storage is if you declare a variable like this:

void myFunction() {
    static int myStatic = 1;
    myStatic++;
}

The first time you call myFunction, it will initialize myStatic to 1, and increase it. The next time you call the function, myStatic will still be 2.

So static variables declared in a function body are 'persistent' over function calls

Edited 5 Years Ago by thelamb: n/a

When a function returns a value, the return is stored temporarily so that the code that called the function can access it. This temporary value doesn't die until the calling code has used it.

What you are experiencing with foo() is normal, your experience with bar() is not. Your definition of bar() is technically correct syntax, but your usage is illegal because you are returning a reference to a local variable. The reason it works is because the string in the memory hasn't been destroyed yet even though s has. Under normal conditions, this should cause a seg fault.

Edited 5 Years Ago by Fbody: n/a

Don't think that is entirely correct. The bar is pretty much equivalent to foo, the pointer to the string is just not directly returned as in foo, but through a variable that holds the same pointer.
So the value of s is returned, not a reference to s itself.

This would be incorrect:

const char** bar()
{
    const char* s = "Hello";
    return &s;
}

This could still work if you're lucky... but the return value will point to the local variable s which at some point will be gone.

Edited 5 Years Ago by thelamb: n/a

Hi, Thank you all for your replies.
Since string literals are stored in a string/text section(stack? I thought string literals are created on stack), and will be permanent to the process, so if I define a lot of string literals, does that mean the program will consume a lot of memory and the memory will only be freed when the program terminates? if not, when will they be destroyed?

char* s = "hello";
s = "world";
s = "a long long string";
s = "another long long string";
....

All of those strings will be in the strings section, not on the stack.

In assembly it would look like
MOV EAX, DWORD PTR[some-fixed-address]

Not all of the strings have to be loaded in memory though, they can reside on disk until necessary.

Try to compile your code and open it in a debugger, like the free OllyDbg and look at the 'strings' tab, you will see all the hard coded strings(and more) that you've used. Or you can use 'strings' on Linux - there must be a Windows variant of that as well but I don't know where from the top off my head, probably in the Visual studio tools somewhere.

OK, I almost understand all about string literals in C++.

This code compiles with GCC and runs without warnings or errors.

#include <iostream>
using namespace std;

class A {
private:
    const char* _str;
public:
    A (const char* str, int) : _str(str) {}
    A (const char* str, double) { this->_str = str; }
    void print() { cout << _str << endl; }
};

int main () {
    A a1("hello", 1);
    a1.print();
    A a2("hello", 1.0);
    a2.print();
    return 0;
}

A few more questions:
1. Is the code showed above correct?
Can I understand it like this:
2. When I need a string member(in a class) that will never need to be changed, I can safely use it the way as the code showed above? and if the string member is supposed to be changed, I MUST stick to std::string?
3. a1 and a2 most probably share the same string constant?


Thank you for your help!

Edited 5 Years Ago by kevintse: n/a

1. I see nothing wrong with your code.
2. Yes.
3. It's up to the compiler whether a1 and a2 share the same string constant.

Your definition of bar() is technically correct syntax, but your usage is illegal because you are returning a reference to a local variable

Correction. bar() returns a copy of the text "world".

Edited 5 Years Ago by firstPerson: n/a

You can test it, by printing what the string points to:

printf( "0x%x\n", _str );

If they point to the same.. the compiler 'optimized' it, but it may very well be that it added both strings.

You can test it, by printing what the string points to:

printf( "0x%x\n", _str );

If they point to the same.. the compiler 'optimized' it, but it may very well be that it added both strings.

I tested it, and both point to the same address.

Thanks a million for your help!!!

This question has already been answered. Start a new discussion instead.