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

che*_*gum 4 c++ memory-management initializer-list c++11

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

Dan*_*ica 9

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

#include <iostream>
#include <vector>

int main()
{
   std::vector<int> v = {

#include "x.inc"

   };

   std::cout << v.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

其中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";
}
Run Code Online (Sandbox Code Playgroud)

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


Jos*_*son 7

这是cppreference必须说的(强调我的):

在原始初始化列表对象的生命周期结束后,不能保证底层数组存在。std::initializer_list 的存储是未指定的(即它可以是自动、临时或静态只读内存,取决于情况)。(直到 C++14)

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

说了这么多,可能不是。我想不出编译器或库作者会选择将它放在堆上的情况,但是“未指定”一词的使用听起来好像无法保证临时数组的分配方式。C++ 标准中可能有更好的规范。

另一个要点是您绝对不应该尝试编写底层数组内存。