【问题标题】:CS50 recover segmentation faultCS50 恢复分段错误
【发布时间】:2020-06-02 13:09:40
【问题描述】:

这是从 pset4 CS50 恢复。我编译的时候没有错误。当我运行代码时,出现分段错误。我不明白到底是什么错误。我已经查找了与其他人发布的分段错误问题相关的解决方案,但它们似乎并没有解决我的问题。

有人可以解释什么是错的,我该如何解决。

#include <stdio.h>
#include <stdint.h>
typedef uint8_t BYTE;

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

if (argc != 2)
{
    printf("Usage: ./recover image\n");
    return 1;
}

FILE *inFile = fopen(argv[1], "r");
if(!inFile)
{
    printf("Could not open file!\n");
    return 1;
}

BYTE buffer[512];
FILE *outFile = NULL;
int imageNum = 0;
char fileName[8];

while (!feof(inFile))
{
     fread(buffer, 1, sizeof(buffer), inFile);
     if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[4] & 0xf0) == 0xef0)
     {
         if (imageNum > 0)
         {
            fclose(outFile);
         }
         imageNum++;
         sprintf(fileName, "%03i.jpg", imageNum);
         outFile = fopen(fileName, "w");
     }
    if (outFile != NULL)
    {
        fwrite(buffer, 1, sizeof(buffer), outFile);
    }
}
fclose(outFile);
fclose(inFile);
return 0;
}

【问题讨论】:

  • fwrite(buffer, 1, sizeof(buffer), outFile);... 你的意思是:fwrite(buffer, sizeof(buffer), 1, outFile);? (fwrite()的定义)
  • 感谢您的帮助。我的 while 循环条件部分是问题所在。现在已经解决了

标签: c cs50


【解决方案1】:

段错误的原因很可能是这个声明:

char fileName[8];

对于大于 999 的文件名,fileName 将溢出。

即为imagenum &gt;= 1000

sprintf(fileName, "%03i.jpg", imageNum);//produces 8 characters + NULL == 9

...会产生"1000.jpg",这是一个缓冲区溢出,因此是segfault。

fileName 变大是解决办法:

char filename[20];//or larger as needed.

还有
根据fwrite()fread() 的定义,以下函数参数放错了位置:

fread(buffer, 1, sizeof(buffer), inFile);
fwrite(buffer, 1, sizeof(buffer), outFile);
               ^        ^

应该是:

fread(buffer, sizeof(buffer), 1, inFile);
fwrite(buffer, sizeof(buffer), 1, outFile);
                     ^         ^

【讨论】:

  • 我根据您提到的内容更改了文件名的大小以及 fread() 和 frwite() 函数,但我仍然遇到分段错误
  • @ZaraK - 有关故障发生的确切位置的更多信息将很有帮助。您是否已经从代码中删除了while (!feof(inFile))。 (请参阅您帖子下的评论。)您是否在调试器中运行? (gdb)
  • 感谢您的帮助。我运行了调试 50,发现问题出在我的 if 条件上。
【解决方案2】:

我通过更改这几行代码找到了上述问题的解决方案

while (!feof(inFile)) 

while (fread(buffer, sizeof(buffer), 1, inFile))

fread(buffer, 1, sizeof(buffer), inFile);
fwrite(buffer, 1, sizeof(buffer), outFile);

fread(buffer, sizeof(buffer), 1, inFile);
fwrite(buffer, sizeof(buffer), 1, outFile);

另外,主要的问题是我的 if 条件,我改变了

if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[4] & 0xf0) == 0xef0)

 if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)

最后的变化

imageNum++;
sprintf(fileName, "%03i.jpg", imageNum);
outFile = fopen(fileName, "w");

sprintf(fileName, "%03i.jpg", imageNum);
outFile = fopen(fileName, "w");
imageNum++;

感谢大家的建议和帮助。

【讨论】:

  • 很高兴您终于能够找到解决方案!您可以让其他人知道此问题已解决的方法是将发布的答案之一标记为已接受的答案(空心复选标记)您的答案是最完整的答案,因此标记它是合适的:)
【解决方案3】:

fileName 被定义为在char fileName[8]; 中有八个元素,但是一旦imageNum 超过 999,sprintf(fileName, "%03i.jpg", imageNum); 就会写入超过八个字符。

【讨论】:

    猜你喜欢
    • 2020-08-02
    • 2021-01-29
    • 2020-12-09
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2019-09-06
    相关资源
    最近更新 更多