即使在离开作用域后,如何访问在堆上分配的变量C++?
How do you access variables that are allocated on the heap in C++ even after leaving the scope?
>我在理解C++中的新关键字时遇到问题。我了解,为了在离开范围后不会从堆栈中弹出内存;您可以将其存储在堆上。但是在此示例中,我收到一条错误消息,指出"标识符 p 未定义"
#include <iostream>
#include <string>
class Person {
public:
int age;
std::string name;
Person() {
}
Person(int a, std::string n): age(a), name(n){}
};
int main() {
{
Person* p = new Person(5, "bob");
}
std::cout << (*p).age;
}
正如您在我的主函数中看到的那样,我创建了另一个作用域,在该作用域中,我在堆上创建了一个 Person 对象,据我所知,该对象在离开大括号后仍然存在,但是为什么它无法识别对象 p?
我尝试取消引用 p,但错误保持不变。 任何帮助都会很棒! 谢谢
您是正确的,该对象仍然存在,因为您从未删除过它。 不过,这只是问题的一半。 名称p
是在其中声明它的嵌套范围的本地名称。 退出该作用域后,p
将被销毁,您将无法再访问您创建的对象。
你需要的是
int main()
{
Person* p;
{
p = new Person(5, "bob");
}
std::cout << (*p).age;
}
现在你可以访问p
,因为它是在main
的范围内声明的。
>Person* p
是一个具有自动存储("局部变量")的Pointer*
类型对象。与任何具有自动存储的对象一样,该指针仅在声明它的作用域结束之前存在。一旦你到达你所做的块范围的闭合}
,就不再有p
这样的东西,那个指针已经停止存在。
虽然p
不存在,但它过去所指向的东西仍然存在。您的Person
泄露并消失了。如果没有指针或对它的引用,就无法将其取回,也无法清理它。确保保留指向它p
或其他指针,直到您delete
它。
将Person* p
声明移到范围之外(或完全删除人为范围)将解决此问题。在这种情况下,p
的生命周期与main
的范围相关联,并且在您尝试std::cout
它是age
成员时仍然存在。
考虑使用智能指针至少避免这样的泄漏。 当最后一个(也是唯一的)指针不再存在时,std::unique_ptr<Person> p
会自动delete
Person
。
对象仍然存在,如果不删除它,则会出现内存泄漏。如果你想在其他地方访问它,你需要保留对它的引用(一般意义上的引用,即指针或引用)。
但是,该变量只能在声明它的范围内访问。例如,您可以通过执行以下操作来修复它:
int main() {
Person* p;
{
p = new Person(5, "bob");
}
std::cout << (*p).age;
delete p;
}
问题是当您在大括号之间创建一个变量时,它将具有块范围。
它将在块结束后死亡(指针 p 本身是 32/64 位值,具体取决于您的机器)。 并且 new 分配的内存仍在 堆,但指针本身不是。(这将导致内存泄漏)。
我不知道你到底想做什么,但你可以做
int main() {
Person * ptr;
{
Person* p = new Person(5, "bob");
ptr = p;
}
std::cout << (*ptr).age;
//free the memory if you will not use it anymore
delete ptr;
}
然后,您可以使用 ptr 指向由 new 创建的块。
Person* p
指针用于存储对象的内存地址,堆上已经分配了内存来存储成员变量,您必须显式使用 Delete 调用默认析构函数来销毁该对象,因为 p 在块中使用,因此不能从外部调用它。
- 何时在函数中声明堆栈分配变量?
- 取消引用指针并立即为其分配变量,导致分段错误
- 在C++中动态分配变量类型
- 在函数 (c++) 中分配变量类型和大小数组
- 无法在命名空间范围内分配变量
- 自我分配变量的定义
- 在 CUDA C++中分配变量 - 无法分配设备变量
- 在 CPP 中动态分配变量的数据类型
- 为什么无法在类主体中分配变量?
- const 类方法是否阻止在类外部分配变量?
- 从文件中分配变量,并使用定界符分配
- 分配指针后,是否可以为指针指向的事物分配变量名称?
- 读取外部文件并在类似xml的输入中分配变量
- 有没有办法在不分配变量的情况下将字符串连接到数字
- 如果使用alloca在内联函数中的堆栈上分配变量,那么在内联函数返回后,其引用是否有效
- 堆分配变量的结构成员对齐
- 包含溢出缓冲区的堆栈分配变量,也称为缓冲区
- 在 GetTransfer 之后,我在帐户 1 收到未分配变量错误。我无法弄清楚我搞砸了什么逻辑错误
- 对动态分配的变量的引用与指向相同动态分配变量的指针
- 在C++中为用户输入分配变量