C / C ++ 有多种方法可以在编译时分配内存。例如,我可以添加全局变量或静态变量。存储值的内存在编译时分配:
int x;
// -- or --
void f() {
static int y;
}
// -- or --
class C {
static int z;
};
int C::z;
但是这个解决方案不能用于分配“内联”内存。是否有可能在一行中执行以下操作?
static int value_behind_x; // does not need to be "named"
int * const x = &value_behind_x;
我的意思是这样的:
int * const x = static_new int;
// -- or --
int * const x_array = static_new int[10];
我知道C / C ++中有一件事允许这样的东西:字符串文字。但是,它们必须是常量,并且不允许将大小指定为数字。
如果没有这种方式,是否有理由或将来可能实施?这样会很好,因为它可以实现像constexpr
这样的std::vector
版本的容器。
答案 0 :(得分:2)
static
将
在编译时分配内存
这表明存在误解。 Static Storage Durration已定义:
对象的存储在程序开始时分配,并在程序结束时解除分配。只存在一个对象实例。在命名空间范围内声明的所有对象(包括全局命名空间)都具有此存储持续时间,以及使用
static
或extern
声明的持续时间。
了解静态存储持续时间对于对抗"static initialization fiasco"。
至关重要通过这种理解,我们可以看到构造指向变量的static
指针没有性能优势,例如 而只是使用地址{{ 1}}如果需要是可取的。static unique_ptr<const int> x(new int(13));
同样的事情适用于分配具有静态存储持续时间的阵列。如果需要对数组进行容器封装,可以使用array
之类的容器: 但一般来说,{{3提供的范围访问和容器访问的改进在c++11中{}},c++14和c++17我建议你坚持:value_behind_x
static array<int, 10> x_array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
修改强>
您知道,iterator library也有静态存储持续时间,这意味着您不会“在编译时分配”。实际上除了C ++使用的静态存储持续时间之外,只有string literals:
- 自动存储持续时间。该对象在封闭代码块的开头分配,并在最后解除分配。除了声明为
static const x_array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
,static
或thread_local的那些外,所有本地对象都有此存储持续时间。- 线程存储持续时间。线程开始时分配对象,线程结束时分配对象。每个线程都有自己的对象实例。只有声明为thread_local的对象才具有此存储持续时间。 thread_local可以与
extern
或static
一起显示以调整链接。- 动态存储持续时间。通过使用动态内存分配函数为每个请求分配和释放对象。
所以不,在运行时之前没有分配或初始化。我也不希望有这种情况,因为这需要一个基本的C ++意识形态改变和在某种程度上改变计算机体系结构。
答案 1 :(得分:1)
首先,具有静态持续时间的变量的内存在编译时并未真正分配。它在链接时或甚至在启动时分配。虽然差异微妙,但在某些情况下很重要。
其次,您正在寻找的是一种分配自动或静态持续时间的数据块的方法。传统上,它使用C样式数组std::array
完成,并在可用时使用VLA扩展作为VLA数组。
答案 2 :(得分:0)
所请求的功能已部分计划用于 C ++ 20 。现在仅允许临时分配。
这意味着new
在编译时将有效。但是,当前不允许在编译时分配的内存泄漏到运行时。可以在P0784中找到此限制的原因。将来的版本中可能会添加对非临时分配的支持。