我不知道这段代码出了什么问题?

时间:2017-12-26 05:58:06

标签: c string pointers malloc

我正在编写一个简单的代码,它接受来自任何长度的用户的字符串并只显示它。但我的代码没有正确执行,因为它接受字符串但没有正确打印它。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
    int i,len;
    static int n=5;
    char a[20];
    char **s;
    s=malloc(5*sizeof(char));
    char *p;
    for(i=0;i<n;i++)
    {
        scanf("%s",a);
        if(*a=='1')                   /*to exit from loop*/
        {
            break;
        }
        len=strlen(a);
        p=malloc((len+1)*sizeof(char));
        strcpy(p,a);
        s[i]=p;
        if(i==n-1)
        {
            s=realloc(s,(5+i*5)*sizeof(char));
            n=5+i;
        }
    }
    for(i=0;i<n-1;i++)
    {
        printf("%s ",s[i]);
    }
    free(p);
    p=NULL;
    return 0;
}

1 个答案:

答案 0 :(得分:4)

有很多问题,但初看起来,最突出的是,

  s=malloc(5*sizeof(char));

错了。 s的类型为char **,因此您需要在那里分配值char *的内存。换句话说,您希望s指向char *元素,因此,您需要相应地分配内存。

要避免这些类错误,请不要依赖硬编码数据类型,而应使用表单

 s = malloc( 5 * sizeof *s);  // same as s=malloc( 5 * sizeof (*s))

其中,大小oid主要由变量的类型决定。两个优点

  • 你可以避免上述错误。
  • 代码变得更有弹性,您不需要更改malloc()语句,以防您选择更改数据类型

也就是说,scanf("%s",a);也有潜在的危险,并且会导致缓冲区溢出超过预期的输入。您应始终使用最大字段宽度限制输入扫描长度,例如

scanf("%19s",a);  // a is array of dimension 20, one for terminating null

那就是说,关于逻辑的建议,当你事先不知道或没有指定输入字符串的长度时,你不能使用字符串类型来< em>扫描输入。完成这项工作的基本方法是

  1. 使用malloc()等分配器函数动态分配中等长度的缓冲区。
  2. 继续逐个阅读输入流,fgetc()或类似。
  3. 如果阅读完成(例如,返回EOF),您已阅读完整的输入。
  4. 如果分配的内存已用完,请重新分配原始缓冲区并继续执行步骤3.
  5. 并且,不要忘记free()记忆。

    否则,您可以使用fgets()来读取内存块并保持真实性如上所述。