c - 我的代码出现分段错误
问题描述
我正在编写一个从存储卡中读取信息的代码(card.raw 是我们提供的,但代码使用用户输入)并使用 jpeg 具有的签名从中提取 jpegs (0xff,0xd8,0xff,0x00 - 0xff)。我遇到了分段错误,因为我使用的是 malloc,但我看不出哪里出错了。我在这里粘贴我的代码,任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
//check terminal usage
if (argc != 2)
{
printf("Usage: ./recover image");
return 1;
}
//open inputted file and check for valid file
FILE *file = fopen(argv[1], "r");
if (!file)
{
printf("Invalid or missing file.");
return 1;
}
BYTE *buff = malloc(512 * sizeof(BYTE));
int counter = 0;
FILE *image = NULL;
char *name = malloc(8 * sizeof(char));
//loop till end of file reached and read a block of input
while(fread(buff, sizeof(BYTE), 512, file) == 1 && !feof(file))
{
bool foundJPEG = buff[0] == 0xff && buff[1] == 0xd8 && buff[2] == 0xff && ((buff[3] & 0xf0) == 0xe0);
//check if found jpeg, and open file for writing
if (foundJPEG)
{
sprintf(name, "%03i.jpg", counter);
image = fopen(name, "w");
}
//if image file open, write to it
if (image != NULL)
{
fwrite(buff, sizeof(BYTE), 512, image);
}
//if found a jpeg already, close it so new one can be written
if (foundJPEG && image != NULL)
{
fclose(image);
counter++;
}
}
free(name);
free(buff);
fclose(image);
fclose(file);
return 0;
}
解决方案
上面的代码存在三个问题,注释中没有提到:
读取成功后,返回值fread
不是 1 而是 512。您交换了 blocksize 和 blockcount -> fread 定义的参数。因此不进入while循环。不要试图通过将大量代码打包到一个语句中来节省空间。如果将返回值和 EOF 的检查分开fread
并使用do ... while()
循环会更聪明。然后你有机会在调试器中看到这个问题。这正是我所做的以及我是如何发现这一点的。
第二个问题是您在抢救前 512 个字节后关闭了图像,但您没有将文件指针image
与语句NULL
一起重置。fclose
结果,代码将重复写入一个关闭的文件,直到找到一个带有 jpg 标头的新块。
第三个问题是你只拯救了 jpg 的前 512 个字节,而不是整个 jpg。您需要扫描输入流中的 jpg 结束指示符FF D9
并复制字节,直到找到为止。-> jpg 格式
推荐阅读
- linked-list - 在链表中包含头节点和尾节点有什么好处?
- debugging - 如何在 CLion 中将所有行设置为断点?
- python - Python super() can't call parent's inherited method
- angular - 自定义 ValidatorFn - Angular 6
- python - scikit 在 jupyter 笔记本上学习
- python - 在节点 js 中设置环境变量并在 python 脚本中使用
- gcc - 在编译中检测 -mconsole 和 -mwindows
- javascript - jQuery 对话框在页面加载时触发,试图在点击时触发
- python - 如何计算与给定ID匹配的多行之间的平均值
- java - Spring Boot 应用程序无法初始化类 org.apache.logging.log4j.util.PropertiesUtil