3

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

所以我写了这样的代码

int arr[UINT_MAX];

当我编译这个时,它说数组维度溢出

但是当我这样写

size_t s = UINT_MAX;
int arr[s]; 

它编译正确。有什么不同

4

6 回答 6

15

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

#include <limits>

size_t s=std::numeric_limits<size_t>::max();

第二个错误:你永远不会得到这么大的数组;由于size_t需要能够表达任何对象的最大大小,它应该可能足够大以表达一个对象,该对象大到应用程序可用的整个地址空间,但尝试分配这样一个大对象将需要专用整个地址空间给它,这是不可行的;此外,您请求的ints 数组那么大,这意味着它将是UINT_MAX*sizeof(int)字节大,这可能是整个地址空间的大约 4 倍 - 显然是胡说八道 - 顺便说sizeof(arr)一下,无法表达大小这样的对象,通常指针甚至无法到达该数组的顶部。编译器会检测到这些错误并阻止您这样做。

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

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

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

长话短说:分配所有内存(甚至无法寻址)是没有意义的,尤其是在堆栈上。使用堆并分配你需要的东西。如果您有特殊要求,您应该研究您的操作系统提供的特殊虚拟内存功能。

于 2010-10-12T20:01:43.787 回答
2

您正在延迟错误。

在这两种情况下,您都要求大约 16GB* 的连续内存,这在 32 位机器上是不可能的。

你的第一次尝试是硬编码大小,你的编译器很好地提前告诉你它不会成功。

您的第二次尝试是使用大小变量,它绕过了编译器警告,但是当您尝试运行程序时它仍然会失败。

*在典型架构上

于 2010-10-12T19:51:28.130 回答
0
size_t s = UINT_MAX;
int arr[s];  

除非您将 s 声明为 const,否则不会编译。另请注意, UINT_MAX 是数组的潜在最大大小。实际上,它不会让您声明一个大小超过几百万的数组。那是因为静态和自动,任何内存都是有限的

于 2010-10-12T19:46:55.613 回答
0
size_t s = UINT_MAX;
int arr[s];

表示 arr 是可变长度数组 (VLA)。我认为每个 C++ 标准都不允许这样做。如果使用编译,我会收到警告

g++ -ansi -pedantic -std=c++98

另外,考虑一下,arr需要UINT_MAX * sizeof( int )字节数。那是相当大!

于 2010-10-12T19:48:16.187 回答
0

你用的是什么编译器?在 VC++ 上,我在两种情况下都会出错(在更正s为 be之后const)。即使它确实编译了,它也会导致未定义的行为,因为UINT_MAX * sizeof(int)肯定不适合您的进程的地址空间,而且整数值本身会溢出并导致错误的大小值。

于 2010-10-12T19:50:11.940 回答
0

对于每个无符号整数类型,最大值应由 -1 表示。例如,在 64 位系统上,以下代码

unsigned char uchar_max = -1;
printf("%u\n", uchar_max);
unsigned int uint_max = -1;
printf("%u\n", uint_max);
unsigned long ulong_max = -1;
printf("%lu\n", ulong_max);
size_t sizet_max = -1;
printf("%lu\n", sizet_max);

返回:

255
4294967295
18446744073709551615
18446744073709551615
于 2013-05-01T08:59:17.837 回答