【问题标题】:fclose() causing a crash in windowsfclose() 导致 Windows 崩溃
【发布时间】:2013-07-03 13:53:54
【问题描述】:

由于某种原因,fclose() 似乎导致我正在编写的程序出错。当它发生时,Windows 终端会显示“进程返回 255”。以下是部分代码:

FILE* output = fopen("random.txt","w");
write(c,output);
//fprintf(output,"shit\n");
fclose(output);

"write" 基本上是将内容写入输出文件。即使程序崩溃,数据也会输出到文件中。写入操作后,我仍然可以写入输出文件,如果我这样做,文本将在那里,但以某种方式关闭文件会导致错误。 有人可以向我解释错误代码可能意味着什么(如果有的话),以及如何解决这个错误?谢谢你。

编辑: "write()" 写入输出文件,仅此而已;它对输出文件所做的唯一事情是 fprintf-ing。它什么也不返回,因为它是一个 void 函数。 没有看到 fclose() 返回什么,因为在我检查返回值之前程序显然崩溃了:\

编辑: 下面是“write()”的细节。我将其更改为“write_insult()”以避免与系统调用混淆。

void write_insult(Composite c,FILE* output){
printf("lol\n");
switch (c->type){
    case SENTENCE:{
        writeSentence(c,output);
        break;
    }
    default: break;
}

}

void writeSentence(Composite c,FILE* output){
FILE* source;
int random = 0;
char* fileName = NULL;
int i = 0;
char* number = malloc(sizeof(char)*2);
if (c->subtype < 10){
    number[0] = '0';
    sprintf(number+1,"%d\0",c->subtype);
}else{
    sprintf(number,"%d\0",c->subtype);
}

fileName = malloc(sizeof(char)*17);
strcpy(fileName,"res/SEN/  /  .txt");
fileName[8] = number[0];
fileName[9] = number[1];
fileName[11] = '0';
fileName[12] = '0';
FILE* tester = NULL;
while ((tester = fopen(fileName,"r")) != NULL){
    i++;
    fclose(tester);
    if (i < 10){
        fileName[12]++;
    }else{
        fileName[11]++;
        fileName[12] = '0';
        i = 0;
    }
}
random = rand()%i;
if (random < 10){
    number[0] = '0';
    sprintf(number+1,"%d\0",random);
}else{
    sprintf(number,"%d\0",random);
}
fileName[11] = number[0];
fileName[12] = number[1];
fileName[17] = 0;
source = fopen(fileName,"r");
Table t = parseFile(source); //remember to free
i = 0;
char* word = NULL;
while (i < t->num){
    if (isInt(t->content[i])){
        word = chooseWord(atoi(t->content[i]));
    }else{
        word = t->content[i];
    }
    fprintf(output,"%s ",word);
    i++;
}
fclose(source);
destroyTable(t);

}

编辑: 我修复了所有字符串问题,但错误仍然存​​在。顺便说一句,如果我改为在 writeSentence 函数中声明文件指针,而不是事先打开文件将其传入,并在函数停止之前将其关闭,不知何故一切都很好。顺便说一下,编译器是 Pelles C 附带的。它之前做过一些不靠谱的事情,难道不是我的错吗?

编辑: 也许我应该通过问来浓缩这个问题:在什么情况下,fprintf 可以在打开的文件上完美地工作,而不是 fclose,它甚至在生成返回值之前就崩溃了?

编辑: 谢谢各位,感谢大家的帮助和建议;我发现我在代码的某处有一个不需要的 fopen 操作。好像是这样,因为问题已经解决了。

【问题讨论】:

  • write 和 fclose 返回什么?
  • 请贴出write()的定义。
  • 发个例子让我们自己复现,不然没办法帮你。见sscce.org
  • 请确保您来自 main 的 exit(0)return 0
  • @meaning-matters 不好笑但很有必要。不可能是 libc 的 write() (至少如果写作真的有效的话)

标签: c


【解决方案1】:

fclose 本身很可能没问题。问题可能是您的代码中其他地方有未定义的行为,这导致程序稍后崩溃。崩溃恰好发生在调用fclose 期间。我可以看到的未定义行为的一个示例是:

fileName = malloc(sizeof(char)*17);
strcpy(fileName,"res/SEN/  /  .txt");

这会将 18 个字节(包括空终止符)写入分配的 17 个字节。写入number 时也会出现类似的缓冲区溢出。当然,在代码的其他地方可能还有其他未定义行为的实例,包括您未显示的函数。尝试找出问题的一种可能方法是禁用部分代码并查看它是否仍然崩溃。

【讨论】:

  • 谢谢,我试试。 C 错误以神秘的方式工作,否则功能似乎很好......
  • 嗯,是的,不是的。如果你在房子里被分配了空间并且任意占用了比你更多的空间,那么那里也会发生不好的事情。顺便说一句,当数字小于 10 时,您不需要填充 sprintf 调用。您可以简单地使用 sprintf(buffer, "%02d", number); - 02d 意味着它将有 2 个字符的宽度,并将填充 '0'
【解决方案2】:
 fileName = malloc(sizeof(char)*17)

正好是一个短字符(忘记了 '\0'?)。也许就是这样

【讨论】:

    【解决方案3】:

    您分配了 2 个字符(比如 2 个字节)

    char* number = malloc(sizeof(char)*2);
    if (c->subtype < 10){
    

    然后你用'0'填充第一个

        number[0] = '0';
    

    然后尝试在其中再添加两个字符。最后一个 null 将溢出您分配的存储空间。在这个位置上,你正处于借来的时间,谁知道会发生什么。如果您损坏了一些密切使用的东西,它可能会在那里损坏。

        sprintf(number+1,"%d\0",c->subtype);
    }else{
    

    这里也是。

        sprintf(number,"%d\0",c->subtype);
    }
    

    尝试为空终止分配至少 3 个字符,并使用像 snprintf 这样的检查字符串副本,它将始终为空终止并且不会离开您的数组。

    始终检查返回码。

    【讨论】:

      【解决方案4】:

      抱歉,不知道这里的情况如何。我没有更多的进展来调查究竟是什么导致了崩溃或 fclose 返回了什么,但似乎代码中的某处存在不需要的 fopen 操作。出于某种原因,这似乎是罪魁祸首,因为问题现在已经消失了。 谢谢大家的帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-23
        • 2020-12-02
        • 2013-11-11
        相关资源
        最近更新 更多