【问题标题】:Odd program behavior with fgets() and initialized variablesfgets() 和初始化变量的奇怪程序行为
【发布时间】:2021-03-14 14:05:16
【问题描述】:

请考虑以下程序代码

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

int main(void)
{
    char *cmd;
    int exitCommand = 1;
    int validCommands = 0;
    int commandValid = 0;

    while(exitCommand != 0)
    {
        printf("> ");
        fgets(cmd, 101, stdin);
        if(*cmd != '\n')
        {
            printf("%s\n", cmd);
        }
        exitCommand = strncmp("exit", cmd, 4);
    }
    return 0;
}

我正在通过gcc -o cmmd cmmd.c 在 Windows 10 x64 cmd 中编译这个程序,然后通过cmmd 运行 该程序似乎意外终止而没有打印输出。 但是,如果我删除了除exitCommand 之外的至少一个变量,或者不初始化除exitCommand 之外的变量,则程序运行正常。 我对导致此问题的原因感到困惑。堆栈内存不应该是一个问题,因为所有这些占用不到 1000000B。 我怀疑fgets() 可能是造成这种情况的原因,但没有可以参考的运行时错误。我是否应该为cmd char 数组分配显式空间?使用的编译器是TDM-GCC。请解释一下这个现象。

【问题讨论】:

  • cmd 是一个未初始化的指针。
  • cmd 需要是一个实际的数组,而不是未初始化的指针。
  • 你能在你的编译器中调高警告级别吗?您正在使用 cmd uninitialized 并且任何最近的编译器都应该抱怨这一点。使用随机内存地址来存储您的输入不是一个好主意。要么使用malloc 保留一些内存,要么将cmd 设为一个数组。
  • 嗨,我可以使用什么编译器指令来提高警告级别? -Werror 工作吗?
  • @mindoverflow 你可以使用-Wall-Wextra-pedantic

标签: c fgets


【解决方案1】:

char* cmd 未初始化。为了能够存储输入,您必须使 cmd 指向有效数组的地址:

char cmd[100];
fgets(cmd, 100, stdin);
// here you can use cmd as a null terminated string

您还应该检查 fgets 返回值以检测任何错误。

【讨论】:

  • 谢谢,我可以通过char *cmd = malloc(101); 纠正这个问题,现在程序可以正常运行了。
  • 使用后记得free(cmd),否则会导致内存泄漏。 (这就是为什么在不需要时避免动态内存分配的原因:这里你在编译时就知道数组的大小,所以你不需要malloc,你可以在堆栈上分配你的数组)
  • 感谢您的提醒,这很重要,但很容易忘记。
猜你喜欢
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 2016-07-15
  • 2016-07-30
相关资源
最近更新 更多