【问题标题】:Where is this memory allocated - heap or stack?这个内存分配在哪里 - 堆还是堆栈?
【发布时间】:2016-02-17 01:45:37
【问题描述】:

我有以下 C++ 代码。由于内存是动态分配的,因此应该在堆上分配。或者,由于内存是在声明时分配的,而不是在任何构造函数中,它是在堆栈上分配的吗?我需要解构器来释放内存吗?

class param{
public:
    char* st = new char[256];
};

在以下情况下会发生什么?我猜这是在堆栈上分配的,不需要使用解构函数来释放。

class param{
public:
    char st[256];
};

第三种方法是写成:

class param{
public:
    char* st;
    param()
    {
        st = new char[256];
    }

    ~param()
    {
       delete[] st;
    }
};

以上三种方法中哪一种是正确的做法?

【问题讨论】:

  • 针对 valgrind 运行第一个版本表示内存泄漏,因此它是在堆上分配的。您必须稍后在某处手动删除,这很弱。第二种或第三种方式都是有效的方法。对于第 3 种方式,请确保您提供合适的(或已删除的)复制和移动构造函数和赋值运算符,以确保正确处理内存所有权。
  • 真的没有任何意义。使用std::vectorstd::array

标签: c++ memory memory-management


【解决方案1】:

由于内存是在声明时分配的,而不是在任何构造函数中,它是在堆栈上分配的吗?

不,它仍然是动态分配的。

我需要解构器来释放内存吗?

你正在通过operator new[]分配内存,所以你需要调用operator delete[]来释放它。

其他建议:

  1. 考虑使用std::vectorstd::array,因为它是C++。

  2. 第三种情况请参考What is The Rule of Three?Rule-of-Three becomes Rule-of-Five with C++11?

【讨论】:

  • 第三种情况很好:它不遵循 3/5/0 的规则。
  • @zenith 特定于 OP' 问题,与第一种情况相比,应该没问题。无论如何,我删除了它,因为它不完全正确。
【解决方案2】:

new 总是分配在堆上。

在第一个示例中,来自new 的指针被放入类成员中。

这个类的一个实例可以在栈上实例化;或者可以通过new 在堆本身上实例化该类的实例。无论以何种方式实例化该类的实例,无论是在堆上还是在堆栈上,其成员 st 将始终指向堆分配的内存。

在第二个示例中,成员 st 是类的一部分。在给出的示例中没有实例化任何内容。这只是一个类声明。当类的实例被实例化时,它可能在堆上或堆栈上被实例化,在任何一种情况下,st 成员都是类的一部分,并与特定的类实例一起被实例化。

至于哪个是“正确”的方式,所有三个例子都可能是正确的。或者他们三个都可能是错的。这完全取决于类的使用方式。一般来说,第 2 或第 3 个示例是最方便的实现方式,并且会产生较少的意外。

但是,可能会想出一些深奥的情况,即使第一个例子也是正确的。

【讨论】:

  • 根据 c++ 标准,在正确的术语中没有像 这样的东西。
猜你喜欢
  • 1970-01-01
  • 2014-10-04
  • 2013-01-10
  • 2010-11-15
  • 2012-07-29
  • 2010-10-26
  • 2016-03-25
  • 2013-07-14
  • 2010-09-30
相关资源
最近更新 更多