使用 size_t 声明最大数组
我想声明一个非常大的数组。我发现数组的最大大小是size_t,它被定义为UINT_MAX,
所以当我编译这个时,我写了这样的代码
int arr[UINT_MAX];
,它说数组维度溢出,
但是当我这样写时,
size_t s = UINT_MAX;
int arr[s];
它可以正确编译。 有什么区别
i wanted to declare a very large array. i found that the max size of an array is size_t, which is defined as UINT_MAX
so i wrote the code like this
int arr[UINT_MAX];
when i compile this, it says overflow in array dimension
but when i write like this
size_t s = UINT_MAX;
int arr[s];
it compiles properly.
what's the difference
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
第一个错误:
size_t
不一定是unsigned int
,因此它的最大值可能与unsigned int
的值不同 (UINT_MAX< /代码>);此外,在 C++ 中,要获取有关类型限制的信息,应使用 std::numeric_limits。
第二个错误:你永远不会得到这么大的数组;由于
size_t
需要能够表示任何对象的最大大小,因此它可能应该足够大以表示一个与应用程序可用的整个地址空间一样大的对象,但尝试分配这么大的大小对象需要将整个地址空间专用于它,这是不可行的;此外,您请求的int
数组那么大,这意味着它将是UINT_MAX*sizeof(int)
字节大,这可能约为 4 倍整个地址空间 - 显然是无意义的 - 顺便说一句sizeof(arr)
将无法表达此类对象的大小,并且通常指针甚至无法到达该数组的顶部。编译器会检测到这些错误并阻止您这样做。此外,我推断您正在尝试在堆栈上分配该内容,该内容通常比应用程序可以使用的所有内存小得多,并且一般来说,在那里分配大数组并不是一个好主意(您应该使用堆)。
第三个错误:分配所有内存没有意义。如果你有很大的内存需求,你应该在堆上分配东西,而不是在堆栈上,并且只分配与操作系统和其他应用程序一起运行所需的内存(如果你正在工作,最后一个考虑因素不适用)在嵌入式系统上,您是唯一正在运行的应用程序)。
C++ 中的第二个片段甚至不应该工作,因为,如果该东西在堆栈上分配,那么您将变得非标准,因为它将是一个 VLA(在 C99 中可用,但被当前和下一个 C++ 标准强烈拒绝) 。然而,在这种情况下,分配该数组的代码是在运行时使用的(VLA 通常在维度上不固定),因此对编译器的检查并不明显(尽管我认为这可以很容易地被优化器,如果 VLA 语义与常规数组没有不同,则可以优化 VLA 并尝试创建常规数组 => 这将因我所说的相同原因而失败)。
长话短说:分配所有内存(您甚至无法寻址)是没有意义的,尤其是在堆栈上。使用堆并只分配您需要的内容。如果您有特殊要求,您应该研究操作系统提供的特殊虚拟内存功能。
First error:
size_t
is not necessarilyunsigned int
, thus its maximum value can be different from the one ofunsigned int
(UINT_MAX
); moreover, in C++ to get informations about the limits of a type you should usestd::numeric_limits
.Second error: you won't ever get an array so big; since
size_t
is required to be able to express the biggest size of any object, it should probably big enough to express an object big as the whole address space available to the application, but trying to allocate such a big object would require to dedicate the whole address space to it, which is infeasible; moreover, you're requesting an array ofint
s that big, which means that it will beUINT_MAX*sizeof(int)
bytes big, which will probably be about 4 times the whole address space - clearly nonsense - and by the waysizeof(arr)
wouldn't be able to express the size of such object, and in general pointers couldn't even reach the top of that array. The compiler detects these faults and stop you from doing that.Moreover, I infer that you're trying to allocate that thing on the stack, that is usually much much smaller than all the memory that the application can use, and in general it's not a good idea to allocate big arrays there (you should use the heap for that).
Third error: allocating all that memory doesn't make sense. If you have big memory requirements, you should allocate stuff on the heap, not on the stack, and allocate just the memory you need to play along well with the OS and the other applications (this last consideration do not apply if you're working on embedded systems where you are the only application that is running).
The second snippet in C++ shouldn't even work, since, if that thing is allocated on the stack, you're going nonstandard, since it would be a VLA (available in C99 but strongly rejected from the current and the next C++ standard). However, in that case the code to allocate that array is used at runtime (VLAs in general are not fixed in dimensions), so the check for the compiler is not obvious to do (although I suppose that this thing could be spotted easily by the optimizer, which, if VLA semantic is not different from regular arrays, could optimize away the VLA and try to make a regular array => which would fail for the same reasons I stated).
Long story short: it makes no sense to allocate all that memory (that you couldn't even address), especially on the stack. Use the heap and allocate just what you need. If you have special requirements, you should investigate the special virtual memory functions provided by your OS.
你这是在拖延错误。
在这两种情况下,您都需要大约 16GB* 的连续内存,这在 32 位计算机上是不可能的。
您的第一次尝试是对大小进行硬编码,并且您的编译器足够好,可以提前告诉您它不会成功。
您的第二次尝试是使用大小变量,它绕过了编译器警告,但当您尝试运行程序时它仍然会失败。
*关于典型架构
You are delaying the error.
You are asking for about 16GB* of contiguous memory in both cases, which is impossible on a 32 bit machine.
Your first attempt is hard-coding the size, and your compiler was nice enough to tell you in advance that it will not succeed.
Your second attempt is using a variable for the size, which has bypassed the compiler warning, but it will still fail when you attempt to run the program.
*On typical architectures
除非将 s 声明为 const,否则不会编译。另请注意,UINT_MAX 是数组的潜在最大大小。实际上它不会让你声明一个大小超过几百万的数组。那是因为静态和自动并且任何内存都是有限的
won't compile unless you declare s as const. Aslo note that UINT_MAX is the potentially greatest size of the array. Practically it won't let you declare an array more than a few million in size. That's because static and automatic and any memory is limited
你使用什么编译器?在 VC++ 上,我在这两种情况下都会遇到错误(将
s
更正为const
后)。即使它确实编译了,也会导致未定义的行为,因为UINT_MAX * sizeof(int)
肯定不适合您的进程的地址空间,而且整数值本身会溢出并导致尺寸值错误。What compiler are you using? On VC++, I get an error in both cases (after correcting
s
to beconst
). Even if it did compile, it would result in undefined behaviour becauseUINT_MAX * sizeof(int)
certainly won't fit in your process' address space, and further the integer value itself would overflow and result in the wrong value for size.表示 arr 是一个可变长度数组 (VLA)。我认为 C++ 标准不允许这样做。如果使用编译,我会期望出现警告
另外,想一想,
arr
需要UINT_MAX * sizeof( int )
字节数。那是相当大了!means arr is a variable length array (VLA). I think it is not allowed per C++ standard. I would expect an warning if compiled with
Also, think about it,
arr
needsUINT_MAX * sizeof( int )
number of bytes. Thats quite big!对于每个无符号整数类型,最大值应用-1 表示。例如,在 64 位系统上,以下代码
返回:
for each unsigned integral type, the maximum should be represented by -1. For example, on a 64-bit system, the following code
returns: