C++ std::数组、std::向量和原始数组的大小

C++ std::数组、std::向量和原始数组的大小,c++,arrays,vector,C++,Arrays,Vector,让我们有 std::array <int,5> STDarr; std::vector <int> VEC(5); int RAWarr[5]; 这些计算正确吗?考虑到我没有足够的内存用于std::vector,也无法逃避动态分配,我应该使用什么?如果我知道std::array会降低内存需求,我可以更改程序使array保持静态。这些数字是错误的。此外,我也不认为他们代表了你认为他们代表的东西。让我解释一下 首先是关于他们错了的部分。不幸的是,您没有显示sizeof(in

让我们有

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

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

这些数字是错误的。此外,我也不认为他们代表了你认为他们代表的东西。让我解释一下

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

size_t sizeof_int = sizeof(RAWarr) / 5; // => sizeof(int) == 8
因为这本质上是
sizeof(T)
的定义:它是数组中
T
类型的两个相邻对象的开头之间的字节数。这恰好与
STDarr
的数字打印不一致:类模板
std::array
被指定为嵌入
T
类型的
n
对象数组。此外,
std::array::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
至少包含
5个
元素,
capacity()
必须大于
size()
。而且,
std::vector
的大小是非零的。也就是说,必须始终做到以下几点:

sizeof(RAWarr) < sizeof(VEC) + sizeof(int) * VEC.capacity()
sizeof(RAWarr)
不管怎样,所有这些都与您的实际问题几乎无关:使用
T
的内置数组、
std::array
std::vector
表示
n
类型的
T
对象的开销是多少?这个问题的答案是:

  • 内置数组
    T[n]
    使用
    sizeof(T)*n
  • std::array
    使用与
    T[n]
    相同的大小
  • 一个std::vector(n)
  • 需要一些控制数据(大小、容量,以及可能和可能的分配器)加上至少“n*sizeof(T)”字节来表示它的实际数据。它还可以选择具有大于
    n
    容量()
    除了这些数字之外,实际使用这些数据结构中的任何一个都可能需要额外的内存:

  • 所有对象都在适当的地址对齐。为此,在对象前面可能有额外的字节
  • 当在堆上分配对象时,内存管理系统my除了可用的内存之外,还包括几个字节。这可能只是一个词的大小,但它可能是任何分配机制的幻想。此外,该内存可能位于分配内存之外的其他位置,例如,位于某个哈希表中
  • 好的,我希望这提供了一些见解。但是,下面是一条重要的信息:如果
    std::vector
    无法保存现有的数据量,则有两种情况:

  • 您的内存极低,而且大多数讨论都是徒劳的,因为您需要完全不同的方法来处理仅有的几个字节。如果您使用的是资源极其有限的嵌入式系统,则会出现这种情况
  • 使用
    T[n]
    std::array
    会有太多的数据,这对您没有多大帮助,因为我们讨论的开销通常小于32字节

  • 也许你可以描述一下你实际上想做什么,以及为什么std::vector
    不是一个选项。

    你能用不同大小的容器运行相同的实验吗,例如,6?将所有5变为6,回答:
    48
    44
    24
    对于STDarr,VEC,您关心的是静态开销大小还是每个元素的额外大小?
    std::array
    没有开销。您将对
    std::array
    元素进行两次计数,因为它实际上是使用模板的魔力作为数组存储在类中的。但是,这确实意味着它是固定长度的。您没有考虑对齐方式,如果输出的顺序确实正确,您似乎有一个8字节的对齐方式。我在代码中使用了原始数组,但它工作正常。我认为原始数组可能是原因,所以我尝试了std::vector来确定问题出在原始数组上。然而,它抛出了坏的东西。我不明白;如果我将30000个int同时分配给std::vector和raw array,std::vector的额外内存使用量会比raw array多字节吗?通常一个
    std::vector(n)
    使用
    n分配
    m
    ,上面假设int的大小为8字节,这是非常罕见的。我还没有遇到过一个具有这种内存模型的系统。通常,int将是4个字节或更少,这可能是原始问题所表明的(即,与他的sizeof()的输出对齐)。
    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
    
    sizeof(RAWarr) < sizeof(VEC) + sizeof(int) * VEC.capacity()