admin管理员组

文章数量:1295874

What magic does std::string perform when we take its address using &? The returned address matches the c_str() address. But we know the c_str() is a field somewhere inside the std::string, not the address of the std::string instance itself? How does it do that?

E.g. in this code, it prints "Equal" :

#include <string>
#include <iostream>

int main(int argc, char const *argv[])
{
    std::string s = "Hello, World!";
    auto addr = &s;
    auto addr2 = s.c_str();
    std::cout << std::hex << addr << std::endl;
    std::cout << std::hex << reinterpret_cast<const void*>(addr2) << std::endl;
    if ((void*)addr == (void*)addr2) {
        std::cout << "Equal" << std::endl;
    } else {
        std::cout << "Not equal" << std::endl;
    }
    return 0;
}

What magic does std::string perform when we take its address using &? The returned address matches the c_str() address. But we know the c_str() is a field somewhere inside the std::string, not the address of the std::string instance itself? How does it do that?

E.g. in this code, it prints "Equal" :

#include <string>
#include <iostream>

int main(int argc, char const *argv[])
{
    std::string s = "Hello, World!";
    auto addr = &s;
    auto addr2 = s.c_str();
    std::cout << std::hex << addr << std::endl;
    std::cout << std::hex << reinterpret_cast<const void*>(addr2) << std::endl;
    if ((void*)addr == (void*)addr2) {
        std::cout << "Equal" << std::endl;
    } else {
        std::cout << "Not equal" << std::endl;
    }
    return 0;
}
Share Improve this question asked Feb 12 at 1:02 JF4JF4 4882 silver badges16 bronze badges 8
  • 1 As you mentioned, they shouldn't be equal. On my system with GCC 14.2 they aren't. Each implementation of the string is likely to be different. Try changing the length of the string so a resize takes place. That should change the address returned by c_str. – Rud48 Commented Feb 12 at 1:10
  • 8 This isn't guaranteed, and you're probably hitting short string optimization. – Stephen Newell Commented Feb 12 at 1:10
  • Thanks for the replies. So it's a weird coincidence then. I found this when I std::cout << the address and it printed the actual string, so I checked the address and sure enough it was a null terminated c string. – JF4 Commented Feb 12 at 1:15
  • 2 To test the assertion that you're hitting the short string optimisation ..... Evaluate sizeof(std::string) (which is implementation-defined). Then assign s to a string literal which has length greater than that size. You should observe that your code prints "Not Equal". – Peter Commented Feb 12 at 6:29
  • 2 Inside STL: The string – 許恩嘉 Commented Feb 12 at 9:12
 |  Show 3 more comments

1 Answer 1

Reset to default 15

std::string::c_str() (and std::string::data()) returns a pointer to the string's current character buffer, wherever it resides in memory.

The only way that pointer can be equal to the address of the std::string object itself is if the std::string implementation supports Short String Optimization (ie, character data of a very short length is stored directly in the string object itself, rather than elsewhere in dynamic memory), and the SSO buffer is the 1st data member of std::string. C++ guarantees that the 1st data member of an object is at the same address as the object itself.

But, there is no guarantee that the SSO buffer (if it exists) is the 1st data member. So, do not rely on this behavior.

本文标签: cWhy do these stdstring and cstr() pointer addresses matchStack Overflow