std::array、std::vector和原始数组的大小
Size of std::array, std::vector and raw array
让我们有,
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
会降低内存需求,我可以更改程序使数组变为静态。
这些数字是错误的。此外,我也不认为它们代表了你认为它们代表的东西。让我解释一下。
首先是关于他们错了的部分。不幸的是,你没有显示sizeof(int)
的值,所以我们必须推导它。在你使用的系统上,int
的大小可以计算为
size_t sizeof_int = sizeof(RAWarr) / 5; // => sizeof(int) == 8
因为这本质上是sizeof(T)
的定义:它是数组中T
类型的两个相邻对象的开头之间的字节数。这恰好与STDarr
的数字打印不一致:类模板std::array<T, n>
被指定为嵌入类型为T
的n
对象数组。此外,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()
无论如何,所有这些都与您的实际问题无关:使用T
、std::array<T, n>
和std::vector<T>
的内置数组表示T
类型的n
对象的开销是多少?这个问题的答案是:
- 内置阵列
T[n]
使用sizeof(T) * n
- CCD_ 26使用与CCD_ 27相同的大小
std::vector<T>(n)
需要一些控制数据(大小、容量,可能还有分配器)加上至少'n*sizeof(T)'字节来表示其实际数据。它也可以选择具有比CCD_ 30大的CCD_
除了这些数字之外,实际使用这些数据结构中的任何一个都可能需要额外的内存:
- 所有对象都在适当的地址对齐。为此,对象前面可能有额外的字节
- 当对象被分配到堆上时,除了可用的内存之外,内存管理系统还会包括几个字节。这可能只是一个关于大小的词,但它可能是分配机制想要的任何东西。此外,该内存可能存在于分配内存之外的其他地方,例如某个地方的哈希表中
好吧,我希望这能提供一些见解。然而,这里出现了重要的消息:如果std::vector<T>
无法容纳您所拥有的数据量,则有两种情况:
- 您的内存非常低,大多数讨论都是徒劳的,因为您需要完全不同的方法来处理仅有的几个字节。如果您正在处理资源极为有限的嵌入式系统,就会出现这种情况
- 您有太多的数据,使用
T[n]
或std::array<T, n>
不会有多大帮助,因为我们所说的开销通常小于32字节
也许你可以描述一下你实际上想做什么,以及为什么std::vector<T>
不是一个选项。
- 初始化具有非默认构造函数的std::数组项的更好方法
- 输入std::数组时出现问题
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- C++如何生成std::数组列表
- 捕获lambda中的std::数组
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- std::数组边界检查如何工作?
- 通过unique_ptr访问std::数组
- 初始化 std::数组 of Eigen::Map
- 传递 std::数组变量作为参数
- 在带有模板的函数中传递未知大小的 std::数组.如何更正此代码?
- 如何将 std::find() 与 2d std: 数组一起使用?
- std::数组派生类聚合初始化
- 在std::数组内部使用时,无法从std::函数构造类
- 使用从1到N的数字初始化std数组模板参数
- 正在声明多维std::数组
- 使用std::index_sequence对std::数组初始化进行包扩展
- 使用 std::type T 的数组来构造可从 T 构造的 std::数组
- 从 std::数组创建十六进制代表
- 使用默认值初始化 std::数组