获取临时对象的内部数组的地址
Posted
技术标签:
【中文标题】获取临时对象的内部数组的地址【英文标题】:Taking an address of an internal array of a temporary object 【发布时间】:2021-08-24 14:38:34 【问题描述】:我想确保我正确理解以下代码示例中的错误:
#include <string>
int main()
const char * ptr = std::string("test").c_str();
return 0;
c_str() 成员函数返回指向 std::string 用来存储字符串的内部数组的指针。但是,在分号之后,在这一行创建的临时文件不再存在,内存被释放,从而使指针失效。这是怎么回事?
由于某种原因,在使用 Visual Studio 2019 进行编译时,指针被分配了一个值,但指向一个空字符串,而使用 Clang 编译(通过 android 的 ndk-build)会导致一个值也指向预期的字符串,例如一会儿。
发生了什么事?这仅仅是未定义行为在两个不同编译器中工作方式不同的情况吗?
谢谢
【问题讨论】:
这是怎么回事? 是的。除了为其分配一个新的有效地址之外,对该指针的任何使用都会导致未定义的行为。 提供的代码中没有未定义的行为。如果ptr
被取消引用,那么就会有未定义的行为。 (我不完全确定您是否可以合法地执行if (ptr != nullptr) ...
,它不会取消引用 ptr,但会查看其当前 不再有效 地址值。)
“这仅仅是未定义行为在两个不同编译器中工作方式不同的情况吗?”。是的。您还应该期望未定义行为在不同编译器版本或不同来自同一编译器的编译或不同相同二进制文件的不同运行之间有不同的工作方式。
@Eljay - 为什么这里需要取消引用?从逻辑上讲,在赋值语句之后,它不再认为 ptr 指向包含以空结尾的字符串“test”的内存数组。它可能包含它,也可能不包含,但不能保证。
为什么这里需要取消引用[以获得未定义的行为]?取消对已删除对象内部结构的悬空指针的引用是未定义的行为.
【参考方案1】:
这个讨论的底线是当临时对象被销毁时会创建一个悬空指针
const char * ptr = std::string("test").c_str();
并且在取消引用指针时会发生未定义的行为。
【讨论】:
以上是关于获取临时对象的内部数组的地址的主要内容,如果未能解决你的问题,请参考以下文章
从对象内部的数组中获取数组键(受保护)值(来自 RTM-php 的响应)?
左值与右值的根本区别在于能否获取内存地址,而能否赋值不是区分的依据