c++ - 从 std::string 对象到 char* 的显式转换,而不使用任何 std::string 成员函数
问题描述
这个问题不是关于任何问题,而更多的是一个深入理解.内存布局的问题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
是指向存储的字符串(字符数组)的指针。这就是你得到的。
由于 SSO 应用于您的短字符串,因此该指针指向对象本身内部的缓冲区std::string
,位于其偏移量 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。通常,正如其他人在评论中指出的那样,您的代码可能会导致未定义的行为。
推荐阅读
- javascript - JavaScript 中的图像预加载和顺序显示
- c - Gtk 3.0 文本视图可调整大小
- javascript - 从表单获取输入会导致空错误
- c++ - 包含指向另一个对象 C++ 的指针的对象向量
- php - stripos():传递字符串字符时的非字符串针警告
- python - cv2.seamlessClone() with OpenCV error: (-215:Assertion failed) dims <= 2 && step[0] > 0 in function 'locateROI'
- vue.js - 子组件中发出事件的问题
- elasticsearch - Databricks pyspark 将数据索引到 Elasticsearch
- php - 在同一页面中执行并获取两个查询
- python - scikit learn:如何检查来自 CountVectorize() 的分析器参数是否正常工作