【问题标题】: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”的内存数组。它可能包含它,也可能不包含,但不能保证。
  • 为什么这里需要取消引用[以获得未定义的行为]?取消对已删除对象内部结构的悬空指针的引用是未定义的行为.

标签: c++ visual-c++ clang


【解决方案1】:

这个讨论的底线是当临时对象被销毁时会创建一个悬空指针

const char * ptr = std::string("test").c_str();

并且在取消引用指针时会发生未定义的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多