std::initializer_list会在堆上分配内存吗?

7
简单问题,std::initializer_list是否会堆分配内存?我不是在谈论它的元素项,而是缓存本身以存储元素。

我相信它的目的是在堆栈上临时分配内存(很可能也会被优化掉),而不是作为动态堆分配器。 - ALX23z
1
这是一个实现细节,你不应该关心它,因为它可能在不同的实现之间有所不同,就我所知,标准也没有说明任何内容。 - Jesper Juhl
2个回答

11
以下是关于std::initializer_list的内容翻译(强调为原文):
引用自cppreference网站:
“在原始初始化列表对象的生命周期结束后,底层数组不能保证存在。 std::initializer_list的存储方式是未指定的(即根据情况可能是自动、临时或静态只读内存)。 (直到C++14)
底层数组是类型为const T[N]的临时数组,在该数组中,每个元素从原始初始化列表的相应元素进行复制初始化(除了缩小转换无效)。底层数组的生命周期与任何其他临时对象相同,除了从数组初始化initializer_list对象会像绑定到临时对象的引用一样延长数组的生命周期(具有相同的例外情况,例如用于初始化非静态类成员)。底层数组可以分配在只读存储器中。(C++14以来)”
总之,很可能不会。我想不出编译器或库作者会选择将其放在堆上的情况,但是“未指定”这个词的使用使其听起来好像根本没有保证临时数组如何分配。 C ++标准可能有更好的规范。
另一个要点是您绝对不应该尝试编写底层数组内存。

9

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

#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 << "0\n";
}

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接