-3

Code :

#include <iostream>

using namespace std;

int main() {
    string str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    const char* temp;
    temp = str.substr(0, str.length()).c_str();
    printf(str.substr(0, str.length()).c_str());
    printf(temp);
    const char* test = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    printf(test);
    return 0;
}

Output:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
�$P
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Can someone explain this?

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • 2
    `str.substr(0, str.length())` returns a temporary object. You take `c_str` of that, after which the temporary goes out of scope. Any access to the pointer after that is UB – ChrisMM Sep 04 '21 at 21:41
  • 2
    Unrelated, sending a string to `printf` as the format argument is a recipe for an exploit attack. At a minimum you should use `printf("%s", whatever_you_string_arg_is_goes_here);`, or just `puts` if appropriate to your app. And since this is C++, ideally you're not using `printf` in the first place. – WhozCraig Sep 04 '21 at 21:44

2 Answers2

1

Your compiler should warn you about this line:

temp = str.substr(0, str.length()).c_str();

Warning C26815 The pointer is dangling because it points at a temporary instance which was destroyed.

What is happening, is that str.substr() is creating (and returning) a std::string object, but it's not being assigned to a variable, instead a pointer to its buffer is retrieved with c_str(), but the object itself is being deleted here as well (you can say 'abandoned').

Thus pointer to its buffer is no longer valid. Just by accident there are still some data that partially looks right. Thus you've got undefined behavior.

Pawel
  • 900
  • 2
  • 10
  • 19
1

The way you are assigning temp is creating a dangling pointer. A dangling pointer is a pointer that points to invalid data, in this case, the invalid data is the sub-string you get from str.substring. The sub-string gets released because it is unused in the program, you can correct this by adding a new variable with the sub-string

#include <iostream>

using namespace std;

int main() {
    string str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    const char* temp;
    //this is the importent line.
    string substr = str.substr(0, str.length());
    temp = substr.c_str();
    printf(str.substr(0, str.length()).c_str());
    printf(temp);
    const char* test = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    printf(test);
    return 0;
}
The Sphynx
  • 23
  • 2