新变量的可访问性(范围 "new")

accessibility of a new variable (scope of "new")

这一定是一个已经被问过的问题,但我在任何地方都找不到任何答案...

我的问题很简单:我读到当使用关键字 new 创建变量时,它的范围不受周围 {..} 的限制。 那么为什么这段代码无法编译?

{
std::string * s = new std::string("foo");
}

std::cout << "print : " << (*s) << std::endl;

Visual Sudio 告诉我:"identifier "s" is undefined" 所以范围仍然受限于关键字 "new" ?

这里有些混乱:new std::string("foo"); 分配 一些内存和有用的 returns 该分配的地址。

写入 std::string * s = ... 可让您存储该地址,以便稍后 delete 内存。

但是一旦你越过右大括号,你就不再存储该地址,因为 s 将超出范围。但内存将保持分配状态。

你最终会遇到内存泄漏,因为你无法delete分配你分配的内存。

s的范围受限于周围的{}。该字符串仍然存在于内存中,但您丢失了指向它的指针。内存泄漏。

您混淆了两个不同的概念:名称的 scope 和对象的 lifetime。您还混淆了两个单独的对象:指针变量 s 和它指向的 std::string 类型的对象。

new std::string 创建一个具有 动态生命周期 的对象,该对象会持续到您将其删除。只要您有指向它的指针或引用,就可以从任何地方访问它。它没有名称,因此不涉及范围。

std::string * s 声明了一个具有 块作用域 自动生命周期 的变量。该名称只能在该范围内访问,并且当程序离开该范围时,变量(指针,而不是它可能指向的任何对象)被销毁。

A variable/pointer的词法作用域和它的内存作用域是两个不同的东西。在这里,不能在其声明块之外引用 s。但是,它占用的内存,直到你删除它才可以解决。

Mike 已经回答了这个问题,但为了稍后访问您的记忆,您可以这样做(继续您人为的示例)

std::string *s;
{
    s = new std::string("Hello, World");
}
std::cout << *s << std::endl;

指针的好处是指针声明不调用std::string的默认构造函数,当你使用new时,它调用std::string的构造函数并且为您提供一个指针,指向构建它的堆中的内存。