【问题标题】:Segmentation fault in scanfscanf中的分段错误
【发布时间】:2014-09-27 18:36:46
【问题描述】:

在运行此代码时,我在 scanf() 处遇到分段错误。这可能是由于声明了大型数组(我通过评论数组声明来检查它)。

#include<stdio.h>
int main()
{
    int test;
    //int n,ok,counter,i,j;
    char a[1000][1000];
    int x[1000][1000],y[1000][1000];
    scanf("%d",&test);
    printf("%d",test);
    return 0;
}

既然,我需要这些数组,有人可以建议我如何更正这段代码。

【问题讨论】:

    标签: c


    【解决方案1】:

    问题是您在本地定义了一些巨大的对象。局部变量是在堆栈上创建的,并且堆栈有限制(每个线程)。有时堆栈最大为 1 兆字节。您的阵列将远远超出此范围。我的猜测是你实际上溢出了堆栈。您可以将数组定义移到 main 之外,并且您的程序应该可以工作,因为这些数组不会在堆栈上创建。您还可以通过在main 中设置static 来定义您的数组。这与在外部声明它们的效果相同。

    全局定义的变量(包括未初始化的数组)和static 未初始化的变量(即使它们在函数中)通常放在数据段中并在程序运行时进行初始化。它们也保证设置为全 0。Wiki reference 将 C 中的这个数据区域描述为:

    C 中的 BSS

    在 C 中,没有显式初始化程序的静态分配对象被初始化为零(对于算术类型)或空指针(对于指针类型)。 C 的实现通常使用仅由零值位组成的位模式表示零值和空指针值(尽管这不是 C 标准所要求的)。因此,BSS 部分通常包括在文件范围内(即在任何函数之外)声明的所有未初始化变量以及使用 static 关键字声明的未初始化局部变量。实现还可以将静态分配的变量分配给 bss 部分,该变量初始化为一个仅由零值位组成的值。

    BSS 段不像堆栈那样受到约束。如果资源存在并且您没有超过任何进程配额,BSS 可以使用最多可用内存。

    另一种选择是使用malloc 动态分配数组,这会将它们放在堆上。以下代码将是创建数组的最简单方法。我使用#define 来更清楚什么是行和列。在定义这些数组并分配内存之后,它们可以像任何普通的二维数组一样使用。

    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
        #define ROWS 1000
        #define COLUMNS 1000
        int test;
    
        char (*a)[COLUMNS] = malloc(ROWS * sizeof *a);
        int  (*x)[COLUMNS] = malloc(ROWS * sizeof *x);
        int  (*y)[COLUMNS] = malloc(ROWS * sizeof *y);
    
        a[100][20] = 'X';
        x[4][999] = 666;
        y[500][0] =  42;
    
        scanf("%d",&test);
        printf("%d",test);
    
        free(a);
        free(x);
        free(y);
    
        return 0;
    }
    

    【讨论】:

    • 我在 main 之外声明了数组,现在它工作正常。但是,出于知识的目的,你能告诉我当我们把它放在我们的 main 里面时它有什么不同吗?
    • 我提供了一些示例代码来使用malloc进行数组定义和初始化
    • 注意:不要考虑ROWS * COLUMNS * sizeof(char)ROWS * COLUMNS * sizeof(int),而是考虑ROWS * sizeof *aROWS * sizeof *b
    • 谢谢我很快就创建了答案,当时没有考虑添加该转换。无需两次指定类型。
    【解决方案2】:

    您在堆栈上分配了巨大的内存,这导致stackoverflow! 在这种情况下您应该使用malloc(),它将在堆上分配内存。使用后还需要free()内存。

    这是一个您可以使用的示例代码,我只为a 变量完成了它,您可以为您的xy 变量使用类似的代码:

    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
        char **a; 
        int i, j;
        a = malloc(1000*sizeof(char*));
        for(i=0;i<1000;i++)
        {
            a[i] = malloc(1000*sizeof(char));
            for(j = 0; j < 1000; j++)
            {
                //Your operations
            }
        }
        for(i=0; i< 1000; i++)
            free( a[i]);
        free(a);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-22
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2015-01-09
      • 1970-01-01
      相关资源
      最近更新 更多