这道题不是什么问题,而是深入理解std::string
的内存布局的问题。
我做了一些实验,意识到可以将 std::string
显式转换为 char*
并成功检索存储在 中的“字符串” std::string
对象。问题是,当 std::string
对象的起始地址与 std::string::c_str()
返回的地址不同时,怎么可能呢?方法?
最近,我遇到了从 std::string
对象到 char*
的显式转换。最初,我认为这种转换不适用于 std::string
,但我很惊讶地知道它有效。
int main()
{
std::string TestString = "Testing";
void * pPointerToStringObject = (void *)&TestString;
char * pExplicitlyConvertedString = *((char **)pPointerToStringObject);
printf("Pointer to the string object : %p\n", pPointerToStringObject);
printf("Pointer returned by c_str() : %p\n\n", TestString.c_str());
printf("\"String\" retrieved by explicit conversion of string object : \"%s\"\n", pExplicitlyConvertedString);
}
输出:
Pointer to the string object : 0x7ffd84d3f4a0
Pointer returned by c_str() : 0x7ffd84d3f4b0
"String" retrieved by explicit conversion of string object : "Testing"
最佳答案
这是一个实现问题。假设您正在使用 libstdc++。然后,std::string
的第一个成员是 a pointer to the stored string (char array) .这就是你得到的。
由于 SSO 适用于您的短字符串,因此此指针指向 buffer inside the std::string
object itself, located at its offset 16 (b0 - a0
十六进制)。
例如,如果我们查看 libstdc++ 实现:
_Alloc_hider _M_dataplus; // offset 0 - an address of object - pointer to data
size_type _M_string_length;
enum { _S_local_capacity = 15 / sizeof(_CharT) };
union
{
_CharT _M_local_buf[_S_local_capacity + 1]; // offset 16 - short string stored here
size_type _M_allocated_capacity;
};
_Alloc_hider
中指针的存储位置:
pointer _M_p; // The actual data.
请注意,您的代码可能无法以这种(未定义的)方式与所示实现之外的其他实现一起工作。例如,libc++使用另一种方法来应用SSO。通常,正如其他人在评论中指出的那样,您的代码可能会导致未定义的行为。
关于c++ - 在不使用任何 std::string 成员函数的情况下从 std::string 对象显式转换为 char*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57876214/