std::array、std::vector 和原始数组的大小

Shi*_*bli 2 c++ arrays vector

让我们有,

std::array <int,5> STDarr;
std::vector <int> VEC(5);
int RAWarr[5];
Run Code Online (Sandbox Code Playgroud)

我试图得到它们的大小,

std::cout << sizeof(STDarr) + sizeof(int) * STDarr.max_size() << std::endl;
std::cout << sizeof(VEC) + sizeof(int) * VEC.capacity() << std::endl;
std::cout << sizeof(RAWarr) << std::endl;
Run Code Online (Sandbox Code Playgroud)

输出是,

40
20
40
Run Code Online (Sandbox Code Playgroud)

这些计算正确吗?考虑到我没有足够的内存std::vector并且无法逃避动态分配,我应该使用什么?如果我知道这会std::array导致内存需求降低,我可以更改程序以使数组静态。

Die*_*ühl 5

这些数字是错误的。而且,我认为它们也不代表你所认为的那样。让我解释。

首先是关于他们错误的部分。不幸的是,你没有表现出它的价值sizeof(int),所以我们必须推导它。在您使用的系统上, an 的大小int可以计算为

size_t sizeof_int = sizeof(RAWarr) / 5; // => sizeof(int) == 8
Run Code Online (Sandbox Code Playgroud)

因为这本质上是 的定义:它是数组中sizeof(T)两个相邻类型对象的开头之间的字节数。T这恰好与 for 的数字打印不一致STDarr:类模板std::array<T, n>被指定为嵌入了一个n类型的对象数组。T此外,std::array<T, n>::max_size()是一个产生 的常量表达式n。也就是说,我们有:

40                                               // is identical to
sizeof(STDarr) + sizeof(int) * STDarr.max_size() // is bigger or equal to
sizeof(RAWarr) + sizeof_int * 5                  // is identical to
40             + 40                              // is identical to
80
Run Code Online (Sandbox Code Playgroud)

那就是40 >= 80——一个矛盾。

类似地,第二个计算也与第三个计算不一致:std::vector<int>至少包含5元素并且capacity()必须大于size()。此外, 的std::vector<int>大小不为零。也就是说,以下条件必须始终为真:

sizeof(RAWarr) < sizeof(VEC) + sizeof(int) * VEC.capacity()
Run Code Online (Sandbox Code Playgroud)

无论如何,所有这些与您的实际问题几乎无关:使用、 an和 an的内置数组表示n类型对象的开销是多少?这个问题的答案是:TTstd::array<T, n>std::vector<T>

  1. 内置数组T[n]使用sizeof(T) * n.
  2. Anstd::array<T, n>使用与 a 相同的大小T[n]
  3. Astd::vector<T>(n)需要一些控制数据(大小、容量以及可能的分配器)加上至少“n * sizeof(T)”字节来表示其实际数据。它可能会选择还有一个capacity()比 更大的n

除了这些数字之外,实际使用任何这些数据结构都可能需要额外的内存:

  1. 所有对象都在适当的地址对齐。为此,对象前面可能有附加字节。
  2. 当在堆上分配对象时,除了可用内存之外,内存管理系统还可能包含几个字节。这可能只是一个关于大小的词,但它可能是分配机制想要的任何东西。此外,该内存可能位于分配内存之外的其他位置,例如在哈希表中的某个位置。

好的,我希望这能提供一些见解。然而,这里有一个重要的信息:如果std::vector<T>无法容纳您拥有的数据量,则有两种情况:

  1. 您的内存非常低,并且大多数讨论都是徒劳的,因为您需要完全不同的方法来处理您拥有的少数字节。如果您正在开发资源极其有限的嵌入式系统,就会出现这种情况。
  2. 您使用的数据太多T[n],否则std::array<T, n>不会有太大帮助,因为我们讨论的开销通常小于 32 字节。

也许您可以描述您实际上想要做什么以及为什么这std::vector<T>不是一个选择。