找不到C程序中的分段错误在哪里

时间:2013-08-10 18:08:23

标签: c string

#include<stdio.h>
#include<string.h>
int main()
{
    char a[1000000];
    int i,j;
    int arr[1000000];
    gets(a);
    unsigned long int len=strlen(a);
    if(len<1000000){
    for(i=0,j=len-1;i<len&&j>=0;i++,j--)
                   arr[j]=a[i]-'0';
    }
    return 0;


}

我正在使用此代码将通过键盘输入的数字存储到整数数组中。但是它一直给我分段错误。我不知道它在哪里。我听说gets()不是一个很好的选择, 但我不知道如何使用替代方法来做到这一点。它似乎是一个相当简单的代码。 任何人都可以指出内存泄漏的原因以及原因? 我在Code :: Blocks上使用了调试器,调用堆栈是空的。

4 个答案:

答案 0 :(得分:1)

按如下方式定义数组a

char a[ 1000000 ] = { 0 };

C中字符串的约定是有一个NULL终止符。这确保了两件事:

  1. a不接受上一个堆栈帧的值。
  2. a在结尾处有一个NULL终止符。
  3. <强>注:

    1. 拥有一个长度为100万的数组会很快耗尽你的调用栈。
    2. 考虑使用动态数组以提高空间效率。您需要一次读取一个字节stdin直到EOF或新行发送,实现如下:

      for ( int byte = getchar(); byte != EOF && byte != '\n'; byte = getchar() ) {
        dynarray_Add( dynArray, byte );
      }
      

      ...其中dynArray_Add是一个函数,可以在字符数组中添加一个字符,并在长度达到容量时执行适当的加倍。

      如果您不熟悉动态数组,请阅读更多here

答案 1 :(得分:1)

您已在堆栈上放置了两个非常大的数组。您的进程不太可能使用足够大的堆栈(超过5MB)启动。应使用malloc()或calloc()动态分配数组a和arr,然后使用free()释放。

答案 2 :(得分:1)

获取它的替代方案:

fgets(a, sizeof(a), stdin);

答案 3 :(得分:0)

您的代码存在许多问题。最明显的是你在堆栈上分配了大量内存,即使它本身没有引起问题,这也是一个坏主意。您还使用旧的,不安全的函数(gets)并且您没有进行适当的错误检查。

fgets几乎是gets的替代品,它具有更好的安全性。只需使用fgets( a, 1000000, stdin )调用它,它就不会超出缓冲区的大小。检查NULL的返回值,您将不会有未初始化的内存问题。使用malloc获取内存,您将不会遇到堆栈大小问题(请不要忘记free!)。最后,当长度存储为int时,不要将unsigned long用于循环!在这种情况下,缓冲区的大小意味着它不能是一个无限循环,但它仍然是糟糕的样式(我想你也希望size_t不是unsigned long - 它们恰好在你的系统上是相同的)。