-1
#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

4 回答 4

1

获取它的替代方法是 fgets:

fgets(a, sizeof(a), stdin);
于 2013-08-10T18:21:58.350 回答
1

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

于 2013-08-10T18:18:56.907 回答
1

a如下定义您的数组:

char a[ 1000000 ] = { 0 };

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

  1. a不采用前一个堆栈帧中的值。
  2. a最后有一个 NULL 终止符。

评论:

  1. 拥有一个长度为 100 万的数组将很快耗尽您的调用堆栈。

考虑使用动态数组以提高空间效率。您需要从stdin直到EOF或发送新行开始一次读取一个字节,实现如下:

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

...在哪里dynArray_Add有一些函数可以将一个字符添加到您的字符数组中,并在长度达到容量时执行适当的加倍。

如果您不熟悉动态数组,请在此处阅读更多内容。

于 2013-08-10T18:15:05.927 回答
0

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

fgets几乎可以直接替代gets,而且安全性更好。只需用 调用它fgets( a, 1000000, stdin ),它就永远不会超出缓冲区的大小。检查返回值NULL,您将不会遇到未初始化的内存问题。用于malloc获取内存,您将不会遇到堆栈大小问题(不要忘记free!)。int最后,当长度存储为unsigned long!时,不要将s 用于循环。在这种情况下,缓冲区的大小意味着它不能是无限循环,但它仍然是不好的风格(我认为你也不想size_t——unsigned long它们恰好在你的系统上是一样的)。

于 2013-08-10T18:26:20.730 回答