>  Q&A  >  본문

在C/C++中数组长度的最大值是多少,跟哪些因素有关系?

PHP中文网PHP中文网2764일 전1074

모든 응답(4)나는 대답할 것이다

  • PHP中文网

    PHP中文网2017-04-17 14:57:49

    经过了好长时间,我才勉强总结了一个答案。

    • 首先,如果要确定一个数组的最大长度,我们需要知道它的数据类型,因此,数组的数据类型是其中一个限制因素。因为不同数据类型的元素大小不同。很显然(我们假设int为4字节,char为1字节),数据类型为char的数组的最大长度是类型为int的数组的4倍。

    • 另外,我们不难想到,大小(size)的数据类型,也就是数组下标的数据类型,其实也是一个限制因素。在C/C++中,数组下标的类型是std::size_t,因此数组的大小首先不能超过size_t所能表示的大小。这个数据类型是在库文件stdio.h中通过typedef声明的,对于32位程序它被定义为unsighed int,对于64位程序定义为unsigned long。前者能表示的最大大小为2^32-1,后者为2^64-1。

    • 然后,我又想到了物理内存的大小。这一点不用细说,因为程序运行时一旦超过物理内存的大小,这个程序就会立刻崩溃。

    上面几点都是比较笼统的限制,我们换一个高大上的表达——宏观上的限制因素。下面,我们介绍几个微观上的限制因素

    • 大家应该都知道,数组的分配方式大概有两种方式:静态分配动态分配。再具体点儿的话,根据数组声明的位置,我们可以将数组分为局部数组全局数组。这样讨论的话,就复杂了,我们暂时可以将数组分为四类(只是笔者本人这样划分,不知道官方是否有这样的分类):静态分配的局部数组、动态分配的局部数组、静态分配的全局数组、动态分配的全局数组。

      • 第一种数组分配时,使用的是栈上的空间,因此静态分配得到的局部数组的大小受限于栈的大小。具体来说是数组所在函数栈帧的大小,当然栈帧的大小肯定不能超过栈的大小。如果你对编译器的使用比较熟悉或者你阅读过编译器文档的话,你应该知道如何调整栈帧的大小限制。在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将会提示溢出。

      • 对于第二种数组和第四种数组,我觉得应该划分为一类。本质上它们都是在堆上分配空间,因此它们的大小受限于堆的大小。堆是不连续的内存区域,堆的大小受限于计算机系统中有效的虚拟内存,因此堆的大小一般都比较大。

      • 至于第三种数组,我们知道它是在静态存储区分配内存空间,因此大小自然受限于静态存储区的大小,也叫做BSS(Block Started by Symbol),在汇编语言中,我么也称之为数据段。目前我还不太清楚静态存储区的大小限制,我在我的电脑(Core i3-3110M, 内存8GB)上做过实验发现我所能分配的最大大小大约为剩余内存的1/2。网上有这样说的:“你的常量有多大就多大”,但是还有待考证。

    Note:关于栈帧的概念可以参考《深入理解计算机系统》这本书,或者其他关于计算机体系结构的资料。

    已经整理成博客:C++中数组的最大长度。

    회신하다
    0
  • 天蓬老师

    天蓬老师2017-04-17 14:57:49

    如果是栈上的数组,大小受限于堆栈大小(记得是4MB)。如果是堆的话,就比较大了,理论上可以使用操作系统允许进程使用的最大内存,减去内存中的代码、常量等占用的空间。不过非要全部用上,那么程序离崩溃也就不远了。

    회신하다
    0
  • PHP中文网

    PHP中文网2017-04-17 14:57:49

    和 cpu 的寻址位宽相关,以及和 操作系统 的寻址模式相关

    在虚拟内存的平坦寻址模式下

    32位的指针寻址范围是 2^32 = 4GB

    회신하다
    0
  • ringa_lee

    ringa_lee2017-04-17 14:57:49

    数组可以分别开在堆、栈、静态存储区,看你的需要、CPU的支持程度和操作系统的制约。

    회신하다
    0
  • 취소회신하다