为啥我仍然可以在字符串范围之外访问 std::string::c_str() 返回的 char 指针? [复制]

Posted

技术标签:

【中文标题】为啥我仍然可以在字符串范围之外访问 std::string::c_str() 返回的 char 指针? [复制]【英文标题】:Why can I still access the char pointer returned by std::string::c_str() out of the scope of string? [duplicate]为什么我仍然可以在字符串范围之外访问 std::string::c_str() 返回的 char 指针? [复制] 【发布时间】:2014-12-09 15:18:35 【问题描述】:

字符串指针pp是临时的,为什么删除指针后cout还是正确的?

#include <string>
#include <iostream>
using namespace std;
int main()
    const char* tt = NULL;
       
    string * pp = new string("big");
    tt = pp->c_str();
    cout << "tt->pp:\t" << tt << endl;
    delete pp; 
       
    cout << tt << endl;
    return 0;

输出是:

tt->pp: big
big

【问题讨论】:

未定义行为/线程。 上面提到的duplicate不是一个,因为它是关于访问局部变量的。这个问题是关于访问释放的内存。 @OlafDietsche:超出范围的局部变量有效地释放了内存。副本是正确的,如果您阅读它,您会理解为什么会这样。 @LightnessRacesinOrbit 一点也不,也许我应该为那些装傻的人提供更详细的信息。这里的错误是访问释放的 heap 内存。 @OlafDietsche:选择哪个物理位置来存储std::string 数据有什么关系?它超出了范围。 OP 在问为什么他仍然可以阅读它而不是出现分段错误或其他错误。是一样的。 【参考方案1】:

正确。一点也不。​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​。

【讨论】:

我知道它的格式不正确。当我预计会出现错误或分段错误时,我会问为什么程序会成功输出。 c_str 是在堆上还是在栈上? @ridox:当它存在时,你的实现将它放在哪里并不重要。它现在不存在。你假设访问无效内存总是会给你一个错误或分段错误,但这绝对不是真的。 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。 @SiKing: Q: “为什么我删除指针后cout还是正确的?” A: “不是”。故事结局。这显然既不是批评也不是要求澄清。 系统将此标记为潜在的低质量答案。我同意。如果这确实是答案,那么听起来好像应该将 OP 标记为关闭?

以上是关于为啥我仍然可以在字符串范围之外访问 std::string::c_str() 返回的 char 指针? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 API 级别 30 上使用范围存储无法访问某些音频文件?

为啥 Lambda 变量范围存在于 LINQ 查询之外?

如何在javascript中访问当前范围之外的变量?

快速访问正文或范围之外的数组值

为啥在嵌套函数之外声明一个计数器变量会使循环慢 5 倍?

为啥在释放指向它的指针后仍然可以访问结构的成员?