Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my pointer becomes dangling pointer in c++?

Tags:

c++

My main language is C#, and I'm learning opengl with scarce c++ background.

// readShaderSource returns const string

// no warning
auto vShaderStr = readShaderSource("vshader.glsl");
auto vShaderSource = vShaderStr.c_str();

// dangling pointer warning
auto vShaderSource = readShaderSource("vshader.glsl").c_str();

What I thought about dangling pointer is something like this:

int* a()
{
    auto a = 10;
    return &a

    // a dies here, so &a becomes dangling pointer
}

which does not seem to be the case.

Why should I have to go through string variable? Isn't it okay to directly access member function? Is there something to do with return value optimization? I'm pretty confused...

like image 988
MyBug18 Avatar asked Mar 01 '23 13:03

MyBug18


1 Answers

What I thought about dangling pointer is something like this ... which does not seem to be the case.

It is the same case, actually. Just in a different form.

The pointer returned by std::string::c_str() is valid only for as long as the std::string object remains alive (and unmodified).

readShaderSource() returns a temporary std::string object. That temporary goes out of scope and is destroyed at the end of the full statement that calls readShaderSource().

So, in this code:

auto vShaderSource = readShaderSource("vshader.glsl").c_str();

The temporary std::string object goes out of scope and is destroyed on the ; after c_str() exits. Thus you are left with a dangling pointer to freed memory.

Whereas in this code:

auto vShaderStr = readShaderSource("vshader.glsl");
auto vShaderSource = vShaderStr.c_str();

You are saving the temporary std::string to a local variable, and then the temporary is destroyed on the ; after readShaderSource() exits. You are then calling c_str() on that local variable, so the returned pointer will remain valid for as long as that local variable remains in scope.

like image 195
Remy Lebeau Avatar answered Mar 11 '23 10:03

Remy Lebeau