【问题标题】:Segmentation fault (core dumped) read from stdin从标准输入读取的分段错误(核心转储)
【发布时间】:2013-04-09 19:05:30
【问题描述】:

我正在尝试计算文件中每个单词的数量。该文件可以是标准输入,也可以是命令行上提供的文件名 (./count -f )。到目前为止,当从命令行读取文件时,程序给出了正确的输出。但是当我尝试从标准输入读取时会发生错误。该程序首先输出正确,然后给出分段错误(核心转储)。这是我的代码的一部分。

    FILE * fp;
int size = 20000;
char sentence[2000]; // the sentence from stdin
if ( argc != 3 ) 
{
    fgets(sentence,sizeof(sentence),stdin); // read from stdin
    fflush(stdin);
    // I think the initialization of word is incorrect, but i do know why it is incorrect
    char *word = strtok (sentence," !\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~\n\t");
    while (word != NULL)
    {
        get_word(word); // get each word
        word = strtok (NULL, " !\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~\n\t");
    }
}
else
{
    fp = fopen( argv[2], "r" );
    if ( fp == 0 )
    {
        printf( "Could not open file\n" );
    }

           char word[1000];
    while (readFile(fp, word, size)) {  // let the program read the file
        get_word(word); // get each word. Works well.
    }
}

get_word 函数:

void get_word(char *word){
node *ptr = NULL;
node *last = NULL;

if(first == NULL){
    first = add_to_list(word); // add to linked list
    return;
}

ptr = first;
while(ptr != NULL){
    if(strcmp(word, ptr->str) == 0){
        ++ptr->freq;
        return;
    }
    last = ptr;            
    ptr = ptr->next;  
}
last->next = add_to_list(word); // add to linked list

}

请帮我弄清楚为什么会出现分段错误(核心转储)。 该程序可以在我的 Mac 上运行,但不能在 Linux 上运行。
提前致谢。

【问题讨论】:

  • fflush(stdin) 触发未定义的行为。 get_word 是做什么的?
  • 这不是根本原因,但您不应该调用fflush(stdin);——输入流未定义 fflush。
  • 不,这不是 fflush(stdin) 问题。我删除了它,但仍然得到错误。我认为这是一个内存问题。该程序可以在我的 mac 上运行,但不能在 Linux 上运行。
  • 在哪一行崩溃?
  • @user605947 请发get_word的代码。它是段错误原因的主要候选者。

标签: c segmentation-fault


【解决方案1】:

问题是

int main (int argc, char *argv[]) {
    FILE * fp;

    if ( argc != 3 )
    {
            fgets(sentence,sizeof(sentence),stdin);
            // and so on
    }
    else
    {
            fp = fopen( argv[2], "r" );
            if ( fp == 0 )
            {
                    printf( "Could not open file\n" );
            }
            while (readFile(fp, word, size)) {
                    get_word(word);
            }
    }

    // do some stuff, sorting etc.

    fclose(fp);

那你fclose(fp)不管它是否被打开。如果fp 未连接到有效流,则分段错误很常见。显然,某些实现可以优雅地处理 fcloseNULL 参数,这就是它在 Mac 上似乎可以工作的原因。

fclose 调用移动到else 分支,当fopen 失败时,不要只是

printf( "Could not open file\n" );

但结束程序。

【讨论】:

  • 非常感谢丹尼尔。大帮助。我真的很感激。
  • 不客气。帮助(和有趣的谜题)是我在这里的原因。
【解决方案2】:

句子大小为 2 kib,而您正在从标准输入读取 2 kib。之后,您在其上使用字符串函数。字符串以 '\0' 结尾,但是由于您读取 2 个没有 '\0' 的 kib 数据,因此没有字符串结尾,因此它会出现段错误,因为字符串函数(在本例中为 strtok)可能工作得远远超过 2亲。

【讨论】:

  • 我只测试了一个字符。
猜你喜欢
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 2021-06-03
相关资源
最近更新 更多