在C++中编程查找最大静态数组大小

8

我很好奇在C++中是否有可能确定数组的最大大小。

    #include <iostream>

    using namespace std;

    #define MAX 2000000

    int main()
    {
      long array[MAX];
      cout << "Message" << endl;
      return 0;
    }

这段代码可以成功编译,但一旦运行就会导致分段错误(即使数组实际上并未被引用)。我知道问题出在数组大小上,因为如果我将其更改为1000000,则可以正常运行。
所以,有没有某个定义或某种方法可以让#define MAX成为我机器上允许的数组最大值?
我实际上并不需要这个,这个问题只是出于好奇。

你只是想了解堆栈中的最大数组大小吗?也许递归对你有用?不是单个数组,而是以组合方式实现? - tartar
2
@tar 这与递归有什么关系? - Cody Gray
这篇文章并没有回答你的问题,但是它讨论了同样的段错误问题,应该是一篇有趣的阅读:https://dev59.com/lnRA5IYBdhLWcg3wuAYo - K Mehta
3
这个数组不是静态的,是自动的。 - R.. GitHub STOP HELPING ICE
1
@tar 我非常清楚递归是什么,但我不明白它与这个问题有什么关系。仅仅因为局部变量和函数调用都在堆栈上存储信息,并不意味着你可以通过递归来解决问题。你如何递归地定义对象来保存数据? - Cody Gray
显示剩余7条评论
4个回答

10

这个问题无法在静态情况下确定,因为实际限制取决于给定的线程栈空间大小。您可以创建一个新线程,并给它10兆字节的栈大小,这样您就能分配相应更大的本地数组。

在堆栈上可以分配的内存量还取决于目前已经使用了多少内存。


这很有道理,我想我不太明白静态数组和动态数组在运行时内存分配方面的区别。 - SirGuy
3
在声明本地变量时,整个数组的空间将从堆栈空间中分配(这与一些其他语言(如Java)不同)。当您在函数外部声明全局变量时,链接器设置内存地址,以便在程序开始运行之前即存在该空间。堆栈大小有限(通常为现代桌面操作系统上的1兆字节,但可能会有很大差异),而静态可用空间是机器的整个应用程序地址空间(32位系统约为2 GB)。 - Greg Hewgill
这两种内存类型之间有性能差异吗?此外,即使它们没有运行,_所有_程序都使用相同的静态空间?在静态空间中是否存在某些共享,或者如果您安装了大量程序,您可能会用完它?我猜这方面的问题不经常出现。 - SirGuy
CPU 对这两种类型的内存没有任何区别,它们只是带有数据的地址。应用程序之间的地址空间不会共享,除非它们明确地合作做到这一点。静态数据空间是在运行时分配的,而不是在安装时。 - Greg Hewgill
好的,我被措辞搞糊涂了。 - SirGuy

4
void foo(int level){
 int dummy[100];
 cerr<<level<<endl;
 foo(level+1); 
}

然后,也许你可以将最后一个打印级别的值乘以400字节。我猜递归调用占用了大部分堆栈空间,但你可以得到一个下限。我对内存管理的理解可能有所遗漏,因此欢迎指正。

这是我在我的机器上使用不同的虚拟数组大小获得的结果。

level   array size    stack total
24257     100      9702800
 2597    1000     10388000
  260   10000     10400000
  129   20000     10320000
   64   40000     10240000
   25  100000     10000000
   12  200000      9600000

我尝试了一下增加整数数组大小的解决方案,只是为了消除每个步骤中额外的函数调用负担。我得到的最大值是当数组大小为10000时,在我的机器上(ubuntu 10.04)的最大堆栈大小为10400000字节。 - tartar
注意这里的尾调用优化。 - user1203803
@daknok_t 什么是尾调用优化? - SirGuy
如果函数在函数调用后直接返回,则被调用的函数可以使用相同的堆栈帧。 - user1203803

3
大多数在函数内声明的变量都分配在堆栈上,这基本上是一个固定大小的内存块。尝试分配比堆栈大小更大的堆栈变量将导致堆栈溢出,这就是segfault的原因。

通常堆栈的大小为8MB,因此,在64位机器上,long max [1000000]的大小为 8 * 1000000<8MB (堆栈是“安全”的),但是 long max [2000000] 的大小为 8 * 2000000>8MB ,因此堆栈溢出并且程序segfaults。

另一方面,使用 malloc 动态分配数组将内存放入中,这基本上是无界的(在32位机器上为4GB,在64位机器上为17,179,869,184GB)。


1
请阅读this以了解硬件和编译器所设置的限制。我认为你不能立即使用MAX定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接