Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::move - std::string - internal pointer

Tags:

c++

string

move

I'm surprised that s and s2 internal pointer to "sample" are not equal, what is the explanation ?

#include <string>
#include <cassert>

int main()
{
    std::string s("sample"); 

    std::string s2(std::move(s)); 

    assert(
        reinterpret_cast<int*>(const_cast<char*>(s.data())) ==
        reinterpret_cast<int*>(const_cast<char*>(s2.data()))
        ); // assertion failure here    

    return 1;
}
like image 687
Guillaume Paris Avatar asked Jan 01 '26 08:01

Guillaume Paris


1 Answers

Why do you assume that they should be the same? You are constructing s2 from s using its move constructor. This transfers the data ownership from s over to s2 and leaves s in an “empty” state. The standard doesn’t specify in detail what this entails, but accessing s’s data after that (without re-assigning it first) is undefined.

A much simplified (and incomplete) version of string could look as follows:

class string {
    char* buffer;

public:

    string(char const* from)
        : buffer(new char[std::strlen(from) + 1])
    {
        std::strcpy(buffer, from);
    }

    string(string&& other)
        : buffer(other.buffer)
    {
        other.buffer = nullptr; // (*)
    }

    ~string() {
        delete[] buffer;
    }

    char const* data() const { return buffer; }
};

I hope that shows why the data() members are not equal. If we had omitted the line marked by (*) we would delete the internal buffer twice at the end of main: once for s and once for s2. Resetting the buffer pointer ensures that this doesn’t happen.

like image 106
Konrad Rudolph Avatar answered Jan 03 '26 22:01

Konrad Rudolph



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!