Temporary std :: lines returning garbage

I'm still learning C ++, so please bear with me. I am writing a simple wrapper around the file system tracks - I am having strange problems with returning temporary lines. Here is my simple class (this is not exact, but pretty close):

typedef const char* CString; typedef std::string String; typedef boost::filesystem::path Path; class FileReference { public: FileReference(const char* path) : mPath(path) {}; // returns a path String path() const { return mPath.string(); }; // returns a path ac string CString c_str() const { return mPath.string().c_str(); }; private: Path mPath; } 

With a little test code:

 FileReference file("c:\\test.txt"); OutputDebugString(file.path().c_str()); // returns correctly c:\test.txt OutputDebugString(file.c_str()); // returns junk (ie รฎรพรฎรพรฎรพรฎรพรฎรพรฎรพรฎรพรฎรพรฎรพรฎรพรฎ.....) 

I am sure that this is due to temporary ones, but I canโ€™t understand why this would be - should not everything be correctly copied?

+6
source share
3 answers

It looks like mPath.string() returns a string by value. This temporary string object is destroyed as soon as FileReference :: c_str () is returned, so its c_str () becomes invalid. With such a model, it is impossible to create the c_str() function without introducing any class variable or static level for the string.

Consider the following alternatives:

 //Returns a string by value (not a pointer!) //Don't call it c_str() - that'd be misleading String str() const { return mPath.string(); } 

or

 void str(String &s) const { s = mPath.string(); } 
+4
source
 CString c_str() const { return mPath.string().c_str(); }; 

mPath.string() returns a copy of std::string . This copy is stored in a temporary place, which will be destroyed at the end of this expression.

.c_str() returns a pointer to the memory that will be destroyed when the string is destroyed, i.e. at the end of this expression.

You are returning a pointer to memory that is already destroyed.

+8
source

Expression

 OutputDebugString(file.path().c_str()) 

and

 OutputDebugString(file.c_str()) 

similar to what they effectively call the c_str() method on a temporary std::string object and try to use the result of this call. The first calls it directly as a subexpression of file.path().c_str() . The second does this more implicitly: inside the FileReference::c_str() method.

In the first case, the temporary std::string object is explicitly created by calling file.path() as an integral part of the whole expression. In accordance with the rules of the language, the lifetime of this temporary object extends to the end of the whole expression, therefore the temporary and result of the call to c_str() remain valid.

In the second case, a temporary object std::string is created inside the FileReference::c_str() method. This temporary object is destroyed when this method returns, which means that FileReference::c_str() returns a pointer to "dead" data. This is the reason for the "junk" information.

0
source

Source: https://habr.com/ru/post/919895/


All Articles