新变量的可访问性(范围 "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
的构造函数并且为您提供一个指针,指向构建它的堆中的内存。
这一定是一个已经被问过的问题,但我在任何地方都找不到任何答案...
我的问题很简单:我读到当使用关键字 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
的构造函数并且为您提供一个指针,指向构建它的堆中的内存。