std :: array,std :: vector和raw数组的大小

时间:2012-01-08 13:02:18

标签: c++ arrays vector

让我们拥有,

std::array <int,5> STDarr;
std::vector <int> VEC(5);
int RAWarr[5];

我试图将它们的大小视为,

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;

输出是,

40
20
40

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

1 个答案:

答案 0 :(得分:4)

这些数字是错误的。而且,我认为它们不代表你认为它们所代表的东西。让我解释一下。

首先是关于他们错误的部分。遗憾的是,您没有显示sizeof(int)的值,因此我们必须推导它。在您使用的系统上,int的大小可以计算为

size_t sizeof_int = sizeof(RAWarr) / 5; // => sizeof(int) == 8

因为这基本上是sizeof(T)的定义:它是数组中T类型的两个相邻对象的开头之间的字节数。这与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

那是40 >= 80 - 矛盾。

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

sizeof(RAWarr) < sizeof(VEC) + sizeof(int) * VEC.capacity()

无论如何,所有这些与您的实际问题似乎无关:使用{{1}的内置数组表示n类型的T对象的开销是多少? },Tstd::array<T, n>?这个问题的答案是:

  1. 内置数组std::vector<T>使用T[n]
  2. sizeof(T) * n使用与std::array<T, n>相同的尺寸。
  3. T[n]需要一些控制数据(大小,容量,可能和可能的分配器)加上至少'n * sizeof(T)'字节来表示其实际数据。它可能会选择std::vector<T>(n)大于capacity()
  4. 除了这些数字之外,实际使用这些数据结构中的任何一个都可能需要额外的内存:

    1. 所有对象都在适当的地址对齐。为此,对象前面可能还有一个字节。
    2. 当在堆上分配对象时,内存管理系统除了可用的内存外还包括几个字节。这可能只是一个大小的单词,但它可能是分配机制的幻想。此外,该存储器可以存在于除分配存储器之外的其他地方,例如,在某个哈希表中。
    3. 好的,我希望这提供了一些见解。但是,此处出现重要消息:如果n无法保存您拥有的数据量,则有两种情况:

      1. 你的内存极低,大多数讨论都是徒劳的,因为你需要完全不同的方法来处理你拥有的几个字节。如果您正在处理极其资源受限的嵌入式系统,情况就是这样。
      2. 您有太多数据使用std::vector<T>T[n]将没有多大帮助,因为我们所讨论的开销通常少于32个字节。
      3. 也许您可以描述您实际上要做的事情,以及为什么std::array<T, n>不是一个选项。