一个奇怪的分段错误错误

时间:2013-01-15 06:20:26

标签: c

  

可能重复:
  Getting a stack overflow exception when declaring a large array

我的系统是x86-64 linux,这是我的简单代码:

#include<stdio.h>
#define N 1024
int main()
{
    int a[N][N];
    int b[N][N];
    printf("hello world\n");
    return 0;
}

来自objdump的汇编代码:

00000000004004fc <main>:

4004fc: 55                      push   %rbp
4004fd: 48 89 e5                mov    %rsp,%rbp
400500: 48 81 ec 00 00 80 00    sub    $0x800000,%rsp
400507: bf c4 05 40 00          mov    $0x4005c4,%edi
40050c: e8 cf fe ff ff          callq  4003e0 <puts@plt>
400511: b8 00 00 00 00          mov    $0x0,%eax
400516: c9                      leaveq 
400517: c3                      retq   
400518: 0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
40051f: 00 

奇怪的是,这个程序在调用printf()函数时会崩溃。但是,如果我将N定义为512,则此程序运行良好。我不知道为什么。是否有任何堆栈大小限制限制堆栈的内存使用?

有人知道为什么吗?感谢。

4 个答案:

答案 0 :(得分:2)

由于超出堆栈大小而导致错误。要摆脱这种情况,请在堆中创建数组。为此,请使用malloc或其他动态内存分配函数。

像      int *a = malloc(N*N*sizeof(int))这样内存位于堆中。
你还应该通过检查来测试是否为你分配了这个内存:

if(a)
     // do stuff with a

答案 1 :(得分:1)

是的,最大堆栈大小很小,大多数时候小于几个KBs。您正尝试将1024*1024*sizeof(int)=4194304bytes4MBs数据分配到单个堆栈分配中,从而导致崩溃。

有两种方法可以解决这个问题:

1)将内存分配到堆栈外

#include<stdio.h>
#define N 1024

int a[N][N];
int b[N][N];    

int main()
{
    printf("hello world\n");
    return 0;
}

或2)使用main()

malloc()内的堆中动态分配内存
    #include<stdio.h>
    #define N 1024

    int main()
    {
        int **a = malloc(N, sizeof(int*));
        int **b = malloc(N, sizeof(int*));
        for (int i=0; i<N; i++)
        {
          a[i]=malloc(N, sizeof(int));
          b[i]=malloc(N, sizeof(int));
         }
        printf("hello world\n");
        return 0;
    }

注意:完成它所拥有的数据后,不要忘记free()任何动态分配的内存,否则程序会泄漏内存。

答案 2 :(得分:0)

是的,在给定时间内您可以在堆栈上分配的数量有限制。它取决于编译器。在visual studio上,默认大小为1 MB。检查编译器设置以了解大小。我猜是因为你超过这个限制就会崩溃。

答案 3 :(得分:0)

我想我也可以从here借鉴我的答案:

int (*a)[N] = malloc(N * N * sizeof(int));
int (*b)[N] = malloc(N * N * sizeof(int));

现在您可以像原始代码中的2D数组一样访问它们;例如a[50][100] = 37;

完成后,请不要忘记free(a)free(b)