Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use (str1 + str2).c_str()? [duplicate]

Tags:

c++

string

I have tested this code:

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;

int main()
{
    string s1("a"),s2("b");
    const char * s = (s1+s2).c_str();
    printf("%s\n",s);
}

It returns "ab".

As far as I know, since (s1 +s2) is a temporary object and may disappear somehow (I have no idea about that), then const char * s may point to undefined memory and may get dumped.

So is it safe to use the .c_str() like that?

like image 995
Sayakiss Avatar asked Aug 09 '13 12:08

Sayakiss


People also ask

Can STR1 be transformed to STR2 by taking characters from STR3?

The task is to find whether string str1 can be transformed to string str2 by taking characters from str3. If yes then print “ YES”, Else print “ NO”. Input: str1 = “abyzf”, str2 = “abgdeyzf”, str3 = “poqgode”. Therefore str1 is transform into str2.

Does strcmp (STR1 and STR2) evaluate to true?

To put it even more plainly, if the strings are equal, then strcmp returns 0, and since !0 == 1, yes, !strcmp (str1, str2) evaluates to true. You already figured that out in your first post.

What does strstr do in C++?

strstr () function in C/C++ C C++ Server Side Programming Programming strstr () function is a predefined function in “string.h” header file which is used for performing string handling. This function is used to find the first occurrence of a substring let’s say str2 in the main string let’s say str1.

What is strlen() function in string library?

The string library Function Purpose strlen () This function is used for finding a leng ... strcat (str1, str2) This function is used for combining two ... strcmp (str1, str2) This function is used to compare two str ...


3 Answers

It's not safe in your example. It's safe however in

printf("%s\n", (a + b).c_str());

The reason is that temporary values (like the result of a + b) are destroyed at the end of the full expression. In your example the const char * survives the full expression containing the temporary and dereferencing it is undefined behaviour.

The worst part of "undefined behaviour" is that things may apparently work anyway... (UB code crashes only if you're making your demo in front of a vast audience that includes your parents ;-) )

like image 101
6502 Avatar answered Oct 13 '22 22:10

6502


In that example we can just quote the standard:

12.2 Temporary objects [class.temporary]

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.

That is after the semicolon of your line:

const char * s = (s1+s2).c_str(); // <- Here

So here:

printf("%s\n",s); // This line will now cause undefined behaviour.

Why? Because as your object is destructed, you don't know anymore what is at this place now...

The bad thing here is that, with Undefined behaviour, your program may seem to work at the first time, but... It will crash for sure at the worst time...

You can do:

printf( "%s\n", (s1+s2).c_str() );

It will work because the object is not destructed yet (remember, after the semicolon...).

like image 33
Pierre Fourgeaud Avatar answered Oct 13 '22 21:10

Pierre Fourgeaud


It's not safe, but you can easily assign to a new variable, and the pointer will be safe in the scope of that variable:

string s1("a"), s2("b") , s3;
s3 = s1 + s2;
printf("%s\n", s3.c_str());

//other operations with s3
like image 5
Miguel Prz Avatar answered Oct 13 '22 20:10

Miguel Prz