【问题标题】:A weird segmentation fault error [duplicate]一个奇怪的分段错误错误[重复]
【发布时间】:2012-12-29 05:19:02
【问题描述】:

可能重复:
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,则该程序运行良好。我不知道为什么。是否有任何堆栈大小限制限制堆栈使用的内存?

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

【问题讨论】:

  • 在 StackOverflow 上问这个有点讽刺
  • ulimit -s 的输出是什么?
  • ab的定义放在outside怎么样?
  • Weired Seg 故障?不。这是应该的方式......
  • 尼莫,我明白了。在 StackOverflow 上问这个问题很讽刺。 :-)

标签: c


【解决方案1】:

我想我不妨给出我的答案,借自here

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

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

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

【讨论】:

    【解决方案2】:

    是的,最大堆栈大小很小,大多数时候小于几个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) 使用 malloc()main() 内的堆动态分配内存:

        #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()任何动态分配的内存,在你处理完它保存的数据后,否则你的程序会泄漏内存。

    【讨论】:

    • int ** 在这里非常错误。
    • @Nemo 请解释一下原因
    • 好吧,在您进行编辑之前这是非常错误的 :-)。原始代码中的ab 衰减为int *,而不是int **
    【解决方案3】:

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

    喜欢 int *a = malloc(N*N*sizeof(int)) 这种方式内存位于堆中。
    您还应该通过检查来测试是否已为您分配了此内存:

    if(a)
         // do stuff with a
    

    【讨论】:

    【解决方案4】:

    是的,在给定时间您可以在堆栈上分配多少是有限制的。它依赖于编译器。在 Visual Studio 上,默认大小为 1 MB。检查您的编译器设置以了解大小。我的猜测是,因为你超过了这个限制,它就会崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多