在堆栈和堆上创建对象数组

Lig*_*dle 16 c++ arrays heap stack object

请考虑以下代码:

class myarray
{
    int i;

    public:
            myarray(int a) : i(a){ }

}
Run Code Online (Sandbox Code Playgroud)

如何在堆栈上创建myarray对象数组,如何在堆上创建对象数组?

GMa*_*ckG 45

您可以在堆栈上创建一个对象数组:

myarray stackArray[100]; // 100 objects
Run Code Online (Sandbox Code Playgroud)

并在堆(或"freestore"):

myarray* heapArray = new myarray[100];
delete [] heapArray; // when you're done
Run Code Online (Sandbox Code Playgroud)

但最好不要自己管理记忆.相反,使用std :: vector:

#include <vector>
std::vector<myarray> bestArray(100);
Run Code Online (Sandbox Code Playgroud)

向量是一个动态数组,(默认情况下)从堆中分配元素.††


因为您的类没有默认构造函数,要在堆栈上创建它,您需要让编译器知道要传递给构造函数的内容:

myarray stackArray[3] = { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)

或者用向量:

// C++11:
std::vector<myarray> bestArray{ 1, 2, 3 };

// C++03:
std::vector<myarray> bestArray;
bestArray.push_back(myarray(1));
bestArray.push_back(myarray(2));
bestArray.push_back(myarray(3));
Run Code Online (Sandbox Code Playgroud)

当然,你总是可以给它一个默认的构造函数:

class myarray
{
    int i;    
public:
    myarray(int a = 0) :
    i(a)
    {}
};
Run Code Online (Sandbox Code Playgroud)

†对于学究者:C++实际上没有"堆栈"或"堆"/"freestore".我们所拥有的是"自动存储"和"动态存储"持续时间.实际上,这与堆栈分配和堆分配一致.

††如果你想从堆栈中"动态"分配,你需要定义一个最大大小(堆栈存储是提前知道的),然后给vector一个新的分配器,所以它使用堆栈代替.

  • 它在C++中的工作方式与它在C中的工作方式相同; 如果有一种更标准的方法告诉编译器在运行时确定N的堆栈上分配N个字节,我不知道它是什么. (2认同)

Ale*_*ets 6

由于C ++ 11 std::array<T,size>可用于在堆栈上分配的数组。它包装T[size]提供的接口std::vector,但是大多数方法是constexpr。不利的一面是,您永远不知道何时堆栈溢出。

std::array<myarray, 3> stack_array; // Size must be declared explicitly.VLAs
Run Code Online (Sandbox Code Playgroud)

对于分配了堆内存的数组,请使用std::vector<T>。除非您指定自定义分配器,否则标准实现将使用堆内存分配数组成员。

std::vector<myarray> heap_array (3); // Size is optional.
Run Code Online (Sandbox Code Playgroud)

请注意,在两种情况下都需要使用默认构造函数来初始化数组,因此必须定义

myarray::myarray() { ... }
Run Code Online (Sandbox Code Playgroud)

也有使用C的VLA或C ++的选项new,但是您应尽可能避免使用它们,因为它们的使用会使代码易于出现分段错误和内存泄漏。