fgets() 多次使用时 C 程序崩溃

Posted

技术标签:

【中文标题】fgets() 多次使用时 C 程序崩溃【英文标题】:fgets() crashing C program when used more than once 【发布时间】:2016-03-14 12:28:19 【问题描述】:

我声明了一个数组并填充了 3 个字符串(数学、物理、英语)。我使用 fgets() 获取要添加到数组的新主题,这工作正常。但是,每当我复制相同的代码块以从用户那里获取另一个主题时,程序就会崩溃。

为什么会这样?如何从用户获取字符串并将其添加到数组中?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()

    char *subjectName[1000];
    int numOfSubj = 0;
    int numOfUserAddedSubj = 0;

    subjectName[numOfSubj] = "Math";
    numOfSubj++;
    subjectName[numOfSubj] = "Physics";
    numOfSubj++;
    subjectName[numOfSubj] = "English";
    numOfSubj++;

//int k;
//for(k=0; k<1; k++)
//
    // add user
    printf("Enter new subject name: ");
    fgets(subjectName[numOfSubj], 50, stdin);
    numOfUserAddedSubj++;
    numOfSubj++;
//


// add another user
/*printf("Enter new subject name: ");
fgets(subjectName[numOfSubj], 50, stdin);
numOfUserAddedSubj++;
numOfSubj++;*/



// display content of array
int i;
for(i=0; i < ((strlen(subjectName))+numOfUserAddedSubj); i++)

    printf("%s\n", subjectName[i]);



    return 0;

【问题讨论】:

subjectName[numOfSubj] 是一个未初始化的 char * 变量。也就是说,您正在尝试写入无效地址。为每个char 缓冲区动态分配内存(例如subjectName[numOfSubj] = malloc(50))或将其静态声明为subjectName[1000][50] 您将一个未初始化的指针传递给fgets,它的使用方式与您之前分配的指向字符串文字的指针不同。 【参考方案1】:

它在第一种情况下工作,因为您正在使用主题名称初始化 char 数组,因此编译器分配内存。

在 USER 情况下,您需要在从用户获取输入之前分配内存。

fgets(subjectName[numOfSubj], 50, 标准输入); //这里你传递了空字符 数组

为了避免出错

subjectName[numOfSubj] = malloc( 50 ); //memory allocation

 fgets(subjectName[numOfSubj], 50, stdin);

free 内存(由 malloc 分配),只要您完成使用它。

free(subjectName[numOfSubj] );

【讨论】:

非常感谢您的解释!现在可以工作了。 :)【参考方案2】:

请注意subjectNamechar* 类型的数组。 您的前 3 个字符串是静态定义的。 对于您想通过fgets() 获取的字符串,您需要先使用mallaoc 分配内存,然后才能调用fgets()

类似:

subjectName[numOfSubj] = (char *) malloc(50*sizeof(char));
fgets(subjectName[numOfSubj], 50, stdin);

最后不要忘记free分配的内存。 请注意,您可能需要考虑不同的方法。您可以静态定义数组:char subjectName[1000][50] 并使用strcpy() 填充“数学”、“物理”和“英语”。

【讨论】:

【参考方案3】:

您有一个包含 1000 个指针的数组,但与此问题相关的指针不指向任何内容。在调用fgets 之前,您需要为指针分配一些内存malloc,例如

printf("Enter new subject name: ");
subjectName[numOfSubj] = malloc( 50 );
fgets(subjectName[numOfSubj], 50, stdin);

【讨论】:

不太正确,这里前 3 个指针指向字符串字面量。 @MichaelWalz 问题是,“如何从用户那里获取字符串并将其添加到数组中?” 是的,但在问题中,第 3 个指针并不指向任何内容,它们确实指向字符串文字。 @MichaelWalz 感谢您关注无关紧要的问题。我已经更新了我的答案。

以上是关于fgets() 多次使用时 C 程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在一个按钮上点击大约 60 多次我的 iPad 应用程序变慢然后最终崩溃

如何防止多次快速点击 UITableView 的编辑按钮导致应用程序崩溃?

Quickblox VOIP APNS 出现在后台,但应用程序崩溃

使用致命错误刷新tableview时应用程序崩溃:索引超出范围Swift3

C程序在GDB中工作,单独运行时崩溃

尝试使用引用 C 的函数写入文件时程序崩溃