使用size_t声明最大的数组

ame*_*een 3 c++ arrays size-t

我想声明一个非常大的数组.我发现数组的最大大小是size_t,定义为UINT_MAX

所以我写了这样的代码

int arr[UINT_MAX];
Run Code Online (Sandbox Code Playgroud)

当我编译它时,它表示数组维度溢出

但是当我写这样的时候

size_t s = UINT_MAX;
int arr[s]; 
Run Code Online (Sandbox Code Playgroud)

它编译得当.有什么不同

Mat*_*lia 15

第一个错误:size_t不一定unsigned int,因此它的最大值可以与unsigned int(UINT_MAX)中的一个不同; 此外,在C++中获取有关您应该使用的类型限制的信息std::numeric_limits.

#include <limits>

size_t s=std::numeric_limits<size_t>::max();
Run Code Online (Sandbox Code Playgroud)

第二个错误:你不会得到如此大的数组; 因为size_t要求能够表达任何对象的最大大小,它应该足够大以表达一个大的对象作为应用程序可用的整个地址空间,但是试图分配这样一个大对象需要专用整个地址空间,这是不可行的; 而且,你要求一个int大的数组,这意味着它将是UINT_MAX*sizeof(int)大字节,这可能是整个地址空间的4倍 - 显然是无意义的 - 顺便说一句sizeof(arr),无法表达大小这样的对象,一般指针甚至无法到达该数组的顶部.编译器检测到这些错误并阻止您这样做.

此外,我推断您正在尝试在堆栈上分配该东西,这通常比应用程序可以使用的所有内存小得多,并且通常在那里分配大型数组并不是一个好主意(您应该使用堆的那个).

第三个错误:分配所有内存没有意义.如果你有很大的内存需求,你应该在堆上分配东西,而不是在堆栈上分配东西,并且只分配你需要与操作系统和其他应用程序一起运行的内存(如果你正在工作,最后的考虑不适用在您是唯一运行的应用程序的嵌入式系统上.

C++中的第二个片段甚至不能工作,因为如果在堆栈上分配了那个东西,那么你就是非标准的,因为它将是一个VLA(在C99中可用,但在当前和下一个C++标准中被强烈拒绝) .但是,在这种情况下,分配该数组的代码在运行时使用(一般而言,VLA在维度上并不固定),因此对编译器的检查并不明显(尽管我认为这个问题很容易被发现优化器,如果VLA语义与常规数组没有区别,可以优化掉VLA并尝试制作一个常规数组=>这会因为我说的原因而失败.

简而言之:分配所有内存(你甚至无法解决)都没有意义,特别是在堆栈上.使用堆并分配您需要的内容.如果您有特殊要求,则应调查操作系统提供的特殊虚拟内存功能.