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

时间:2015-06-05 14:02:27

标签: c++ arrays pointers memory

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

    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被删除并且它的析构函数被调用时,_dummies的记忆被释放了吗?我理解堆栈上的实例变量是自动释放的,但是MyObject如何知道这个指针指向堆栈上的数组而不是堆上创建的Dummy对象?

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

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

编辑:谢谢大家。现在我明白MyObject与数组的生命周期没有任何关系。当dummies阵列超出范围时,它会被删除。

但是:如果用“char”代替“Dummy”怎么办?在堆栈上有一个char *(例如从函数返回)是非常标准的,并将它传递给一个对象,然后只需将指针保存到第一个char就可以存储它。这也是一个不好的做法吗? (我将使用std :: vector和std :: string代替,更简单......)

5 个答案:

答案 0 :(得分:1)

你需要知道你的实例变量_dummies只是一个指针。创建对象时,传递给构造函数的指针存储在_dummies中,这就是全部。该指针可以是NULL,堆栈上的数组地址,malloc返回的指针,或许多其他东西。你的对象不知道。

如果在对象仍然存在时数组消失,那么在此之后使用该对象时会遇到麻烦。您有责任确保数组仍然存在,直到最后一次访问对象中的_dummies为止。并且您负责在对象消失后以某种方式删除数组本身。因此,除非您仔细使用,否则您的构造稍微处于危险的一面并且会崩溃。

答案 1 :(得分:0)

唯一的问题是,如果您在new课程中使用了Dummy。如果你没有,不需要担心。当堆栈中的对象超出范围时,它们会自动删除。

答案 2 :(得分:0)

  

当obj被删除并且它的析构函数被调用时_dummies的记忆被释放了吗?

不,但这不是问题,如果我理解你的例子,因为_dummies'的记忆。在堆栈上,当它超出范围时将被释放(独立于被销毁的MyObject实例)。

  

我理解堆栈上的实例变量是自动释放的,但是MyObject如何知道这个指针指向堆栈上的数组而不是堆上创建的Dummy对象?

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

  

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

它是堆栈上的数组,而不是指针。当在表达中使用它时,它会衰变。到指针(指向数组中的第一个元素)。因此,它通过引用传递(但不是作为C ++引用!)。

答案 3 :(得分:0)

  

当obj被删除并且它的析构函数被调用时_dummies的记忆被释放了吗?

不,不是。如果你想释放与任何指针相关的内存,你必须明确地这样做,例如如果delete[] _dummies是动态数组,请键入_dummies

  

MyObject如何知道这个指针指向堆栈上的数组而不是指向堆上创建的Dummy对象?

它没有。这意味着如果您在堆栈分配的_dummies超出范围后尝试访问MyObject中的Dummy dummies[2] = {a,b};并被删除,则可能会出现段错误。

  

在构造函数中是通过值或引用传递的虚拟数组?

它的类型Dummy[]被强制转换为指针类型Dummy*,然后按值传递。

答案 4 :(得分:0)

您的Dummy* _dummies;成员变量可能会也可能不会指向某个实际的内存位置。管理此位置是您的责任,而不是默认构造函数。因此,如果使用类外部的指针初始化它,当实例被销毁时,指向的内存不会发生任何事情,只是指针会消失。如果在类中创建(新)实例,则必须在析构函数中释放(删除)它。

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