Amazing output

In the name of Allah

Hello, everyone
I wrote the following sample program but I got an amazing output. I know if I use strdup function, my problem will be solved but I don't want to use this function because I have to free the memory.
Please, help me how to solve this problem.

Thanks in advance

#include <stdio.h>

#include <string>
using std::string;

const char* func1()
{
string str = "hello";

return str.c_str();
}

const char* func2()
{
string str = "hi";

return str.c_str();
}

int main()
{
char s[20];

sprintf( s, "%s\t%s\n", func1(), func2());
printf("%s\n",s);

return 0;
}
~
~
Please use code tags - the <> button on the right.

What was amazing about the output?

I am not clear on why you have a problem.
The problem with this function, as with the other one,

1
2
3
4
5
6
const char* func1()
{
    string str = "hello";

    return str.c_str();
}


is that it is trying to return the address of the C-string in the buffer of the local string str.

When it's constructed, the string object str allocates a buffer on the heap and copies "hello" into it.

The c_str() call then gives you the heap address where "hello" can be found at that moment.

But, as str is a local variable, when you return from func1, its (as in, str's) destructor is fired which frees up the buffer. So you end up returning the address of a C-string which was there when you called c_str() but is now gone.

Possible fixes:

#1 return the string and use c_str() later.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

#include <string>
using std::string;

string func1()
{
    string str = "hello";

    return str;
}

string func2()
{
    string str = "hi";

    return str;
}

int main()
{
    char s[20];

    sprintf( s, "%s\t%s\n", func1().c_str(), func2().c_str());
    printf("%s\n",s);

    return 0;
}


#2 make the strings static, so the destructors don't fire when you return. It also made sense to make them const here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>

#include <string>
using std::string;

const char* func1()
{
    // constructed the first time func1 and still here when we come back
    static const string str = "hello";

    return str.c_str();
}

const char* func2()
{
    // ditto
    static const string str = "hi";

    return str.c_str();
}

int main()
{
    char s[20];

    sprintf( s, "%s\t%s\n", func1(), func2());
    printf("%s\n",s);

    return 0;
}


Andy
Last edited on
closed account (DSLq5Di1)
Would also recommend snprintf() to avert buffer overruns, better yet, consider using <stringstream> and <iostream> for output.
I'm with sloppy when it comes to snprintf() and <iostream>, etc.

I assume what you've coded is just for experimentation purposes.

In the case where a string is returned, main()--as you no doubt know--would display the same output using just

1
2
3
4
5
6
int main()
{
    cout << func1() << '\t' << func2() << "\n\n"; // or use endl?

    return 0;
}
Last edited on
Topic archived. No new replies allowed.