代码之家  ›  专栏  ›  技术社区  ›  TrulyBright

出现分段错误:iogetline。c

  •  -1
  • TrulyBright  · 技术社区  · 7 年前

    以下代码是问题部分:

    #define NICKLEN 10
    ...
    
    typedef char * string;
    typedef struct donation
    {
        string nickname;
        ...
    } Item;
    
    ...
    
    void eatline(void)
    {
      while (getchar()!='\n');
    }
    
    ...
    
    string s_gets(string st, int n)
    {
      string ret_val;
      string find;
    
      ret_val=fgets(st, n, stdin);
      if (ret_val)
      {
        find=strchr(st, '\n');
        if (find)
          *find='\0';
        else
          eatline();
      }
    
      return ret_val;
    }
    
    ...
    
    int main(void)
    {
      Item donate;
    
    ...
    
    puts("Enter y to start");
    
    while(getchar()=='y')
    {
      eatline(); // to remove \n from input
      puts("Enter nickname. Limit is 10 characters.");
      s_gets(donate.nickname, NICKLEN);
    ...
    

    以下是输入、输出

    Enter y to start
    
    y
    Enter nickname. Limit is 10 characters.
    
    ffff
    

    输入昵称时,发生错误(在gdb中):

    iogetline.c: No such file or directory.
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   J...S    7 年前

    成员 nickname 在你的 struct donation Item 是一个 char 指针。所以 donate.nickname 是未初始化的指针。它可以指向任何地方,因为它具有垃圾值。

    该指针中的值被视为内存位置的地址,该内存位置甚至可能不是允许程序访问的内存的一部分。

    非法访问内存时,程序seg会出现故障。

    与您的 fgets() 在里面 s_gets() ,您正在写入指向的内存位置 捐赠昵称

    你可以 结构捐赠

    typedef struct donation
    {
        char nickname[11];
        ...
    } Item;
    

    作为存储的字符串的最大大小 昵称 是10。额外的一个字符用于 \0 性格

    fgets() 读取尾部 \n 也如果你也想存储它,我想你必须将大小修改为12。

    或者,如果需要动态内存分配,请在 Item donate;

    donate.nickname = malloc(sizeof(char)*11);
    

    并在使用完后释放内存

    free(donate.nickname);