简体   繁体   English

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

[英]Creating array of objects on the stack and heap

Consider the following code:考虑以下代码:

class myarray
{
    int i;

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

}

How can you create an array of objects of myarray on the stack and how can you create an array of objects on the heap?如何在堆栈上创建 myarray 的对象数组以及如何在堆上创建对象数组?

You can create an array of objects on the stack via:您可以通过以下方式在堆栈上创建对象数组

myarray stackArray[100]; // 100 objects

And on the heap (or "freestore"):在堆上 (或“freestore”):

myarray* heapArray = new myarray[100];
delete [] heapArray; // when you're done

But it's best not manage memory yourself.但最好不要自己管理内存。 Instead, use a std::vector :相反,使用std::vector

#include <vector>
std::vector<myarray> bestArray(100);

A vector is a dynamic array, which (by default) allocates elements from the heap.向量是一个动态数组,它(默认情况下)从堆中分配元素。 †† ††


Because your class has no default constructor, to create it on the stack you need to let the compiler know what to pass into the constructor:因为您的类没有默认构造函数,要在堆栈上创建它,您需要让编译器知道将什么传递给构造函数:

myarray stackArray[3] = { 1, 2, 3 };

Or with a vector:或使用向量:

// 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));

Of course, you could always give it a default constructor:当然,你总是可以给它一个默认的构造函数:

class myarray
{
    int i;    
public:
    myarray(int a = 0) :
    i(a)
    {}
};

† For the pedants: C++ doesn't really have a "stack" or "heap"/"freestore". † 对于学究:C++ 并没有真正的“堆栈”或“堆”/“freestore”。 What we have is "automatic storage" and "dynamic storage" duration.我们拥有的是“自动存储”和“动态存储”持续时间。 In practice, this aligns itself with stack allocation and heap allocation.在实践中,这与堆栈分配和堆分配保持一致。

†† If you want "dynamic" allocation from the stack, you'd need to define a max size (stack storage is known ahead of time), and then give vector a new allocator so it uses the stack instead. ††如果你想从堆栈中“动态”分配,你需要定义一个最大大小(堆栈存储提前知道),然后给向量一个新的分配器,以便它使用堆栈。

Since C++11 std::array<T,size> is available for arrays allocated on the stack.由于 C++11 std::array<T,size>可用于堆栈上分配的数组。 It wraps T[size] providing the interface of std::vector , but the most of the methods are constexpr .它包装T[size]提供std::vector的接口,但大多数方法是constexpr The downside here is that you never know when you overflow the stack.这里的缺点是您永远不知道何时溢出堆栈。

std::array<myarray, 3> stack_array; // Size must be declared explicitly.VLAs

For arrays allocated with heap memory use std::vector<T> .对于分配有堆内存的数组,使用std::vector<T> Unless you specify a custom allocator the standard implementation will use heap memory to allocate the array members.除非您指定自定义分配器,否则标准实现将使用堆内存来分配数组成员。

std::vector<myarray> heap_array (3); // Size is optional.

Note that in both cases a default constructor is required to initialize the array, so you must define请注意,在这两种情况下,都需要默认构造函数来初始化数组,因此您必须定义

myarray::myarray() { ... }

There are also options to use C's VLAs or C++'s new , but you should refrain from using them as much as possible, because their usage makes the code prone to segmentation faults and memory leaks.也有使用 C 的VLA或 C++ 的new的选项,但您应该尽可能避免使用它们,因为它们的使用会使代码容易出现分段错误和内存泄漏。

If you create an array of objects of class myarray ( either on stack or on heap) you would have to define a default constructor.如果您创建 myarray 类的对象数组(在堆栈上或在堆上),则必须定义默认构造函数。

There is no way to pass arguments to the constructor when creating an array of objects.创建对象数组时,无法将参数传递给构造函数。

I know how to create object with out of the default constructor, but only on stack:我知道如何使用默认构造函数创建对象,但仅在堆栈上:

Suppose you want to create 10 objects for MyArray class with a = 1..10 :假设你想用a = 1..10为 MyArray 类创建 10 个对象:

MyArray objArray[] = { MyArray[1], MyArray[2]......MyArray[10]}

No need to call the destructor, because they are created in the stack.无需调用析构函数,因为它们是在堆栈中创建的。

To use stack memory allocated with a max size, and view it through a standard stl container with a run time chosen size, you can use std::span.要使用以最大大小分配的堆栈内存,并通过具有运行时选择大小的标准 stl 容器查看它,您可以使用 std::span。

#include <span>
using namespace std;

struct Toto{ int i; char name[20];};
Toto mem[100];
int n=3;
std::span<Toto> s(&mem[0], n);

my use case involves a function that gets called a million times and makes use of a few arrays (currently std::vectors).我的用例涉及一个被调用一百万次并使用几个数组(当前为 std::vectors)的函数。 I wonder if it would be faster to replace std::vector this way.我想知道以这种方式替换 std::vector 是否会更快。 Havent't tried yet... Another possibility would be to allocate std::vector's once instead of a million times.还没有尝试过......另一种可能性是分配std :: vector一次而不是一百万次。

#include <stdio.h>
class A
{
public:
  A(int a){ 
       printf("\nConstructor Called : %d\n",a); 
       aM = a;
      }  
  ~A(){ 
    printf("\ndestructor Called : %d\n",aM);
}
private:
  int aM;
};

int main()
{                                                                                                   
  A **a = new A*[10];
  for (int i = 0;i<10;i++)
    a[i] = new A(i+1);
    for (int i = 0;i<10;i++)
      delete a[i];// = new A(i+1);                                                                                    

  delete []a;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM