C++ C++;堆栈上作为指针存储的实例变量

C++ C++;堆栈上作为指针存储的实例变量,c++,arrays,pointers,memory,C++,Arrays,Pointers,Memory,我在堆栈上创建了一个简单虚拟对象数组: Dummy a(8); Dummy b(9); Dummy dummies[2] = {a,b}; 有一个MyObject对象。我在堆栈上创建了它。构造函数将此数组存储到实例变量中 class MyObject{ Dummy* _dummies; MyObject obj(Dummy* dummies): : _dummies(dummies) {

我在堆栈上创建了一个简单虚拟对象数组:

    Dummy a(8);
    Dummy b(9);
    Dummy dummies[2] = {a,b};
有一个MyObject对象。我在堆栈上创建了它。构造函数将此数组存储到实例变量中

    class MyObject{
        Dummy* _dummies;

        MyObject obj(Dummy* dummies):
        : _dummies(dummies)
        {
        }
    };

    MyObject obj(dummies); 
当obj被移除并调用其析构函数时_假人的内存是否被释放?我知道堆栈上的实例变量是自动释放的,但MyObject如何知道该指针指向堆栈上的数组而不是堆上创建的虚拟对象

在构造函数中,dummies数组是通过值还是引用传递的?它是一个指针,但毕竟是堆栈上的一个数组

我理解堆栈、堆、按值和引用传递,但堆栈上用指针处理的数组确实让我感到困惑。我一直使用vector,因为它清晰简单,但我也想了解简单数组

编辑:谢谢大家。现在我知道MyObject与数组的生存期没有任何关系。当dummies数组超出范围时,它将被删除


但是:如果“Dummy”被替换为“char”会怎么样?在堆栈上有一个char*(例如,从函数返回)并将其传递给对象是非常标准的,对象只需保存指向第一个char的指针即可存储它。那也是一个坏习惯吗?(我将使用std::vector和std::string代替,更简单…

您唯一关心的问题是您是否在
虚拟类中使用了
new
。如果你没有,没必要担心。当堆栈上的对象超出范围时,它们会被自动删除

当obj被移除并调用其析构函数时_假人的内存是否被释放

不,但如果我正确理解了您的示例,这不是问题,因为“虚拟内存”位于堆栈上,当它超出范围时将被释放(与正在销毁的MyObject实例无关)

我知道堆栈上的实例变量是自动释放的,但MyObject如何知道该指针指向堆栈上的数组而不是堆上创建的虚拟对象

没有。如上所述,MyObject析构函数不会自动释放dummies指向的任何分配内存

在构造函数中,dummies数组是通过值还是引用传递的?它是一个指针,但毕竟是堆栈上的一个数组

它是堆栈上的数组,而不是指针。在表达式中使用时,它会“衰减”到指针(指向数组中的第一个元素)。因此,它是通过引用传递的(但不是作为C++引用)。 当obj被移除并调用其析构函数时_假人的内存是否被释放

不,不是。如果要释放与任何指针关联的内存,则必须显式执行此操作,例如,如果
\u dummies
是动态数组,则键入
delete[]\u dummies

MyObject如何知道该指针指向堆栈上的数组而不是堆上创建的虚拟对象

没有。这意味着,如果您尝试在
MyObject
中的
\u dummies
中访问分配给堆栈的
dummie[2]={a,b}超出范围并被删除您可能会遇到segfault

在构造函数中,dummies数组是通过值还是引用传递的


它的类型
Dummy[]
被强制为指针类型
Dummy*
,然后通过值传递成员变量可能指向也可能不指向某个实际内存位置。管理此位置是您的责任,而不是默认构造函数的责任。因此,如果使用类之外的指针初始化它,当实例被销毁时,指向的内存将不会发生任何变化,指针将消失。如果在类中创建(新建)实例,则必须在析构函数中释放(删除)它


从实用的角度来看,您可能需要考虑智能指针,如C++ 11中的STD::SysDypPTR,使这些任务不易出错。

< P>您需要知道实例变量伪哑只是一个指针。创建对象时,传递给构造函数的指针存储在_dummie中,仅此而已。该指针可以是NULL、堆栈上数组的地址、malloc返回的指针或许多其他内容。你的目标不知道


如果在对象仍然存在时数组消失,那么如果在此之后使用对象,则会遇到麻烦。在上次访问对象中的_dummies之前,您负责确保数组仍然存在。在对象消失后,您负责以某种方式删除数组本身。因此,您的构造稍微有点危险,如果您不小心使用,它将崩溃

你有什么“新”的东西吗?如果没有,就不必担心。除非你用“new”创建了内存,否则就不必担心释放它。当它超出范围时,它将从堆栈中弹出。数组本身根本不会传递给构造函数。构造函数接收到指向数组第一个元素的指针。如果它指向的数组是在堆栈上分配的,则不应
delete[]\u dummies
,就像OPs问题中那样。