CS50 恢复段错误
CS50 recover segmentation fault
这是从 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;
}
fileName
被定义为在char fileName[8];
中有八个元素,但是一旦imageNum
超过999,sprintf(fileName, "%03i.jpg", imageNum);
就会写入超过八个字符。
段错误的原因可能是这个声明:
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.
还有,
根据 fwrite() and 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);
^ ^
我通过更改这些代码行找到了上述问题的解决方案
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++;
感谢大家的建议和帮助。
这是从 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;
}
fileName
被定义为在char fileName[8];
中有八个元素,但是一旦imageNum
超过999,sprintf(fileName, "%03i.jpg", imageNum);
就会写入超过八个字符。
段错误的原因可能是这个声明:
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.
还有,
根据 fwrite() and 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);
^ ^
我通过更改这些代码行找到了上述问题的解决方案
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++;
感谢大家的建议和帮助。