1

In one of my project, i initialized a const std::string& with a const char (know at compile time), and the result of print it was ... surprising.

I use gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) on Ubuntu 12.04x32

Exemple:

#include <string> #include <iostream> using namespace std; class A { public: A() : str("test"){}; const string& str; }; int main(int argc,char* argv[]) { A a; cout<<a.str<<endl; return 0; }; 

So, normaly, it will show "test" but, this is a prt of the output I have:

testP�����utf8)����lower_case_table_names�xW�xW� �� ����127.0.0.1utf8W�Y127.0.0.1 via TCP/IP127.0.0.1 �5.5.31-0ubuntu0.12.04.1rootW�rootW�1����metadata_use_info_schema!P�XP�� VARaءpW�P4:����SHOW SESSION VARIABLES LIKE 'lower_case_table_names'`(���TCP/IP (3)@!K!K!� ..... <charset name="gb2312"> <family>Simplified Chinese</family> <description>GB2312 Simplified Chinese</description> <alias>chinese</alias> <alias>iso-ir-58</alias> <collation name="gb2312_chinese_ci" id="24" order="Chinese"> <flag>primary</flag> <flag>compiled</flag> </collation> <collation name="gb2312_bin" id="86"> <flag>binary</flag> <flag>compiled</flag> </collation> </charset> 

the output continu for 1000 lines.

So my question is simple: WHY? (I try to add a \0 at the end of "test", but no change)

0

3 Answers 3

11

That is because you are dereferencing a dangling reference, which gives your program undefined behavior. Per paragraph 12.2/5 of the C++11 Standard:

[...] A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits. [...]

That means the temporary std::string object to which str is bound in the constructor's initialization list will be dead by the time you dererefence str.

You have two ways out of this. Either make your data member str a const char*, or make it an std::string (not a reference type). I would personally go for the last option:

class A { public: A() : str("test") { } std::string str; }; 

Also notice, that you don't need a semicolon after function definitions.

Sign up to request clarification or add additional context in comments.

2 Comments

@AndyProwl that's what I thought but was not really sure, I prefer to ask questions there. What amazes me is that it does not crash.
@Krozark: That is because this is undefined behavior. It may crash (it does for me) or may not (it does not for you). You can't make assumptions on a program with undefined behavior.
2

Initializing a string & requires a string and you are providing a const char *. The compiler generates a temporary string, initializes the string & and then destroys the string leaving you with undefined behavior when you try to use the reference.

Comments

1

You bind str reference to a temporary std::string that vanishes when the constructor exits.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.