【问题标题】:Getting segmentation fault while scanning an integer value扫描整数值时出现分段错误
【发布时间】:2016-01-21 21:12:17
【问题描述】:

虽然这很奇怪,但我在扫描整数值时遇到了分段错误。

这是我的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int t,n,i,j;
    char c;
    int grid[1000][1000],right[1000][1000],down[1000][1000];
    scanf("%d",&t);
    printf("hello\n");
    while(t--)
    {
        scanf("%d",&n);

        memset(right, 0, sizeof(int) * 1000 *1000);
        memset(down, 0, sizeof(int) * 1000 *1000);

        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%c",&c);
                printf("CHAR = %c\n", c);
                if(c == '.')
                    grid[i][j] = 1;
                else
                    grid[i][j] = 0;
            }
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                printf("%d",grid[i][j]);
            }
        }
    }
    return 0;
}

执行gdb 会在scanf("%d",&amp;t); 行显示分段错误。我不知道这是怎么回事?

[在 linux 32 位机器上使用 gcc-4.8.4]

【问题讨论】:

  • 堆栈溢出老兄!您的本地数组 gridrightdown 每个大约 4 MB。让它们 static 成为丑陋的“快速修复”,或者更好地动态分配它们。
  • 1000*1000*3.检查网站名称
  • 哦!!!在那种情况下,为什么编译器没有在分配的静态内存中抛出错误。也许是因为我可以在 1 个系统上编译我的二进制文件并在不同的系统上运行?
  • ..因为它是提供段限制的链接器,而不是编译器。它不是静态的,它是本地的:自动存储。您可以将它与一个非常大的堆栈段链接,它会运行。
  • 如果你真的需要,你可以在运行时增加堆栈大小 - 参见例如this answer - 这只是最后的手段,例如用于需要大量工作才能正确修复的糟糕编写的遗留代码。

标签: c segmentation-fault


【解决方案1】:

设置您的链接器以指示加载程序分配一个最大堆栈段限制,该限制足够大以适合您的大型本地数组。

【讨论】:

    【解决方案2】:

    问题在于您的数组:gridrightdown 太大而无法放入堆栈。

    就没有编译错误的原因而言:

    因为这段代码在语法或语义方面没有任何问题。链接器也没有任何问题。

    当加载器尝试加载程序并在堆栈上分配那么多内存时,就会出现问题。在 Linux 系统上,堆栈通常为 8 MB,而您的阵列超过了这个。

    您可以将它们设为静态(如 cmets 中所建议的那样),因为静态成员分配在 bss 或数据段上。但实际上你需要重新考虑是否需要这么大的数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      相关资源
      最近更新 更多