为什么我的代码10000*10000的二维数组可以运行,别人的500*500的就不行了?

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 0x3f3f3f3f
#define vexnum 10000
typedef struct n{
    int Adjmatrix[11111][11111];
}MG;
int flag[11111] = {0},n,m;
MG x;
int random_num()
{
    int ran;
    
    ran = rand() % 10000 + 1;
    
    return ran; 
}
void Dij(int t[],int lw[])
{
    int i,j,k,min;

    for(i = 1; i <= vexnum; i++){
        lw[i] = x.Adjmatrix[1][i];
        t[i] = 1;
    }

    t[0] = -1;
    flag[1]=1;

    for( i=2 ; i <= vexnum ; i++){
        min = MAX;

        for( j=1 ; j<=vexnum ; j++ ){
            
            if( !flag[j] && lw[j]<min ){
                min = lw[j];
                k = j;
            }
        }

        flag[k] = 1;

        for( j=2; j<=vexnum ; j++){

            if( !flag[j] && min+x.Adjmatrix[k][j] < lw[j] ){

                lw[j] = min + x.Adjmatrix[k][j];
                t[j] = k;
            }
        }
    }
}
int main()
{
    int i,j,sum=0;
    int path[11111],lowcost[11111];
    int u,v,w,pre;

    srand( (unsigned)time( NULL ) );
    //建立矩阵
    for(i=1;i<=vexnum;i++)
        for(j=1;j<=vexnum;j++){

            x.Adjmatrix[i][j] = MAX;
        }

    for(i = 1; i <= vexnum; i++){
        m = random_num();
        for(j = 1;j <= m; j++){
            v = random_num();
            w = random_num();
                    
            if(x.Adjmatrix[i][v] > w && i != v){
               x.Adjmatrix[i][v] = w;
           }
    }
    }

    Dij(path,lowcost);
    for(i = 2; i <= vexnum; i++){
        sum = sum + lowcost[i];
    }
    
    printf("%d\n",sum);

    freopen( "lowcost.txt", "w", stdout );
    for(i = 1; i <= vexnum; i++){
        printf("lowcost[%d] : %d\n",i,lowcost[i]);
    }
    freopen( "path.txt", "w", stdout );    
    for(i = 1; i <= vexnum; i++){
        pre = i;
        printf("v1--v%d : %d\n",pre,lowcost[i]);
        if(lowcost[i] == MAX){
            printf("v1 to v%d has no shortest path\n",i);
        }
        else{
             do{
                printf("v%d<--",pre);
                 pre = path[pre];
                }while(pre != 1);
        
                printf("v1\n");
            }
        }
    return 0;
}
阅读 4.7k
3 个回答

你的程序表明你开的是局部变量而不是全局变量(关于全局和局部变量你可以参考C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别)。
所以你的数组是开在栈上的,这就涉及到编译期限制栈大小的问题。如果你申请这么大的数组是会stackoverflow的,我记得我原来用devc++写oj的时候开了一个100000的数组好像就爆栈了,但是现在换到osx的clion下面好像没事了...
在一般情况下, 不同平台默认栈大小如下(仅供参考)

SunOS/Solaris 8172K bytes (Shared Version)

Linux 10240K bytes

Windows 1024K bytes (Release Version)

AIX 65536K bytes

当然你可以修改你的默认栈大小:

1.SunOS/Solaris系统:
limit # 显示当前用户的栈大小
unlimit # 将当前用户的栈大小改为不限制大小
setenv STACKSIZE 32768 #设置当前用户的栈大小为 32M bytes

2.Linux系统:
ulimit -a #显示当前用户的栈大小
ulimit -s 32768 #将当前用户的栈大小设置为32M bytes

3.Windows (在编译过程中的设置)

  • 选择 "Project->Setting".
  • 选择 "Link".
  • 选择 "Category"中的 "Output".
  • 在 "Stack allocations"中的"Reserve:"中输栈的大小,例如: 32768

在 Visual Studio 开发环境中设置此链接器选项

  • 打开此项目的“属性页”对话框。有关详细信息,请参见设置 Visual C++ 项目属性。
  • 单击“链接器”文件夹。
  • 单击“系统”属性页。
  • 修改下列任一属性:
  • 堆栈提交大小
  • 堆栈保留大小

Reference

如果有很大的结构或者数据,不要把它定义为局部变量,因为一般编译器在生成程序的时候,会设置一个有限的栈大小,当然这个值可以通过设置编译参数来修改。在程序启动的时候,就会给它生成一个给定大小的栈,局部变量、函数参数都会存放在栈中,一旦空间用尽,就会栈溢出,程序就崩溃了。
有几种办法避免这种情况:

  1. 使用全局变量
  2. 使用静态变量
  3. 使用动态分配,如果真的只在函数中使用这个数据,可以这样处理:

    void foo()
    {

    int *p;
    
    p = new int[1000000];
    
    ... // Do something
    
    delete[] p;

    }

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题