std::initializer_list 堆是否分配内存?

Does std::initializer_list heap allocate memory?

本文关键字:分配 内存 是否 list initializer std      更新时间:2023-10-16

简单的问题,std::initializer_list堆会分配内存吗?我不是在谈论它的元素项,只是存储元素的缓冲区本身。

以下是 cppPreferred 要说的(强调我的(:

在原始初始值设定项列表对象的生存期结束后,不保证基础数组存在。std::initializer_list 的存储未指定(即它可以是自动、临时或静态只读内存,具体取决于情况(。 (至C++14(

基础数组是 const T[N] 类型的临时数组,其中每个元素都是从原始初始值设定项列表的相应元素复制初始化的(缩小转换无效除外(。基础数组的生存期与任何其他临时对象相同,只是从数组初始化initializer_list对象会延长数组的生存期,就像将引用绑定到临时对象一样(具有相同的例外,例如初始化非静态类成员(。底层数组可以在只读内存中分配。 (自C++14起(

总而言之,可能不是。我想不出编译器或库作者会选择将其放在堆上的情况,但是"未指定"一词的使用听起来像无法保证如何分配临时数组。C++标准中可能有更好的规范。

另一个要点是,您绝对不应该尝试写入底层阵列内存。

这是一个有趣的问题。我同意乔希的回答,只是想补充一点,我创建了以下相关实验。我尝试编译并运行以下代码:

#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {
#include "x.inc"
};
std::cout << v.size() << std::endl;
}

其中x.inc包含 100M 乘以0,加上尾随0,由此程序生成:

#include <fstream>
int main()
{
std::ofstream f("x.inc");
for (int i = 0; i < 100000000; i++)
f << "0, ";
f << "0n";
}

使用 GCC 创建的最终可执行文件有 328 MB,这表明std::intializer_list的整个实例实际上呈现在程序的数据段中。运行时,没有分段错误,Valgrind 报告除了向量v所需的 400 MB 之外没有堆分配。