即使离开范围,如何在C ++中访问在堆上分配的变量?

问题描述 投票:0回答:4

我在理解C ++中的new关键字时遇到问题。我知道,为了不让内存在离开范围后从堆栈中弹出;您可以将其存储在堆上。但是,在此示例中,我收到一条错误消息,提示“标识符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的引用,但错误仍然相同。任何帮助将是巨大的!谢谢

c++ heap new-operator scopes
4个回答
1
投票

您正确地认为该对象仍然存在,因为您从未删除它。不过,这只是问题的一半。名称p对于在其声明的嵌套作用域而言是本地的。退出该作用域后,p被破坏,并且您将无法再访问创建的对象。

您需要的是

int main() 
{
    Person* p;
    {
        p = new Person(5, "bob");
    }

    std::cout << (*p).age; 
}

现在您可以访问p,因为它已在main的范围内声明。


0
投票

Person* p是具有自动存储功能的Pointer*类型对象(“局部变量”)。像任何具有自动存储功能的对象一样,该指针只存在到声明它的作用域的末尾为止。一旦到达所创建的块作用域的结尾},就不再有p这样的东西了,指针已停止存在。

虽然p不存在,但它所指向的内容仍然存在。您的Person泄漏并消失了。没有指针或对其的引用,将无法取回它,也无法对其进行清理。确保保留p或其他指针,直到您delete

Person* p的声明移到范围之外(或完全删除人工范围)将解决此问题。在这种情况下,p的生存期与main的范围相关联,并且在您尝试将其作为std::cout成员时仍将存在。

请考虑使用智能指针至少避免这种泄漏。当最后一个(也是唯一的)指针不再存在时,age将自动将std::unique_ptr<Person> p设置为delete


0
投票

该对象仍然存在,并且如果不删除它,则会发生内存泄漏。如果要在其他位置访问它,则需要保留对其的引用(一般意义上的引用,即指针或引用)。


0
投票

问题是,当您在花括号之间创建变量时,它将具有块作用域。

© www.soinside.com 2019 - 2024. All rights reserved.