CS50恢复分段故障

时间:2020-06-02 13:09:40

标签: c cs50

这是从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;
}

3 个答案:

答案 0 :(得分:1)

发生段错误的原因可能是以下声明:

char fileName[8];

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

即为imagenum >= 1000

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

...将产生"1000.jpg",这是缓冲区溢出,从而导致段错误。

使fileName更大可以解决:

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


根据{{​​3}}和fwrite()的定义,以下函数参数放错了位置:

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

应该是:

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

答案 1 :(得分:1)

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

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++;

谢谢大家的建议和帮助。

答案 2 :(得分:0)

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