【问题标题】:C++ - Array of pointers to object, what is stored in STACK and what in HEAP?C++ - 指向对象的指针数组,什么存储在堆栈中,什么存储在堆中?
【发布时间】:2013-07-28 08:47:06
【问题描述】:

我是 C++ 的新手,我想澄清一些关于使用运算符“new ...”和运算符“delete ...”的内存管理的要点。

我会发布一些我的代码,如果有错误,请您纠正我的 cmets。

我也在处理虚函数和接口,这通过阅读代码很清楚,我还问你我是否以正确的方式接近它们。

那我有一个更直接的问题,什么时候应该使用“new[] ...”或“delete[] ...”,应该如何正确使用?

PS:下面代码的输出是:

car built
motorcycle built
car has 4 wheels
motorcycle has 2 wheels
car destroyed
motorcycle destroyed

这是main.cpp的来源:

#include <iostream>

using namespace std;

class vehicle
{
    public:
        virtual
        ~vehicle()
        {
        }

        virtual void
        wheelNum() = 0;
};

class car : public vehicle
{
    public:
        car()
        {
            cout << "car built" << endl;
        }

        ~car()
        {
            cout << "car destroyed" << endl;
        }

        void
        wheelNum()
        {
            cout << "car has 4 wheels" << endl;
        }

};

class motorcycle : public vehicle
{
    public:
        motorcycle()
        {
            cout << "motorcycle built" << endl;
        }

        ~motorcycle()
        {
            cout << "motorcycle destroyed" << endl;
        }

        void
        wheelNum()
        {
            cout << "motorcycle has 2 wheels" << endl;
        }

};

int
main()
{
    // motorVehicle[2] is allocated in the STACK and has room for 2 pointers to vehicle class object

    // when I call "new ...", I allocate room for an object of vehicle class in the HEAP and I obtain its pointer, which is stored in the STACK

    vehicle* motorVehicle[2] = { new (car), new (motorcycle) };

    for (int i = 0; i < 2; i++)
    {
        // for every pointer to a vehicle in the array, I access the method wheelNum() of the pointed object

        motorVehicle[i] -> wheelNum();
    }

    for (int i = 0; i < 2; i++)
    {
        // given that I allocated vehicles in the HEAP, I have to eliminate them before terminating the program

        // nevertheless pointers "motorVehicle[i]" are allocated in the STACK and therefore I don't need to delete them

        delete (motorVehicle[i]);
    }

    return 0;
}

谢谢大家。

【问题讨论】:

  • 对于每个new T,您需要一个delete,对于每个new T[...],您需要一个delete []。你的代码看起来不错。
  • 您发布的代码运行良好。考虑使用智能指针,例如std::shared_ptrstd::unique_ptr,用于管理堆分配内存的生命周期。
  • 如果我使用 new[] 分配 motorVeichle[2] 会怎样?我应该声明一个指向指针数组的指针吗?
  • 不,new[] 返回一个指向第一个元素的指针,因此您仍然需要声明一个指向车辆的指针:vehicle* p = new vehicle[2];。请记住使用delete[] 将其删除。如果要分配数组数组,则需要一个指向数组的指针:int(*p)[5] = new int[5][x];
  • @iMineLink 你不应该。什么场景需要new[]

标签: c++ arrays pointers heap-memory stack-memory


【解决方案1】:

关于您的代码:指针数组是一个局部变量, 这将在堆栈上分配。他们的指针是什么 在您的示例中, self 指向的是分配的 动态(在堆上)。

关于“更直接的问题”:我还没有找到任何案例 应该使用new[]。它存在的原因是 完整性,但它并没有任何合理的用途。

【讨论】:

  • 在我发布的静态情况下,你是对的,但是如果我想在运行时分配我的数组怎么办?来自您使用的一些 Java 经验:Object[] array = new Object[n];(您可以使用 ArrayList,这是真的,但让垃圾收集器做一些工作......)和来自 C 的地方:int* p; p = calloc(sizeof(int), n); 这里我认为更直接的方法是用new[] 然后delete[] 那么... 但是如果你说用它不是很合理,那么动态内存管理应该用什么代替呢?
  • @iMineLink 要动态分配数组,请使用std::vector。 C++ 不是 Java; C++ 默认具有值语义。 (在 Java 中,无论您使用 ArrayList 还是 new Object[n] 都不会改变垃圾收集器的任何内容。)
  • @iMineLink 也许更重要的是:C++ 和 Java 之间的一个重要区别是,在 C++ 中,除非您确实需要,否则您不会在 C++ 中使用动态分配。而且你几乎不需要它,除了实体对象类型,它有身份并且(可能)是多态的。数组不是实体对象类型。
【解决方案2】:

new 分配的内存在堆上,其他的都在栈上。所以在你的代码中,你有

vehicle* motorVehicle[2] = { new (car), new (motorcycle) };

栈上有一个由两个指针vehicle*[2]组成的数组,堆上有两个对象,一个car和一个motocycle

那么你有两个循环

for (int i = 0; i < 2; i++)

每一个都在循环期间在堆栈上创建一个整数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2015-02-17
    • 2015-03-13
    • 2017-01-13
    • 2014-08-14
    相关资源
    最近更新 更多