得到分段错误:iogetline.c

时间:2018-03-10 12:33:34

标签: c segmentation-fault

以下代码是问题部分:

#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 个答案:

答案 0 :(得分:1)

nicknamestruct donation中的成员Itemchar指针。所以,donate.nickname是一个未初始化的指针。它可能指向任何地方,因为它具有垃圾价值。

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

非法访问内存时,程序会出错。

fgets()中使用s_gets(),您正在写入donate.nickname指向的记忆位置。

您可以将struct donation设为

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

因为nickname存储的字符串的最大大小为10.额外的一个字符用于\0字符。

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

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

之后添加以下行
donate.nickname = malloc(sizeof(char)*11);

并在完成使用后释放内存

free(donate.nickname);