CS50恢复-为什么我总是遇到分段错误?
我是一个完全的编程初学者,我真的不明白哪里出了错。我看了别人的代码,修改了很多东西,但都没用:如果有任何帮助,我将不胜感激CS50恢复-为什么我总是遇到分段错误?,c,segmentation-fault,cs50,recover,C,Segmentation Fault,Cs50,Recover,我是一个完全的编程初学者,我真的不明白哪里出了错。我看了别人的代码,修改了很多东西,但都没用:如果有任何帮助,我将不胜感激 #include <stdio.h> #include <stdlib.h> #include <stdint.h> int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage ./recover image\n"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage ./recover image\n");
return 1;
}
FILE *card = fopen(argv[1], "r");
if (card == NULL)
{
printf("ERROR\n");
return 1;
}
int jpeg_num = 0;
typedef uint8_t BYTE;
BYTE buffer[512];
char filename[10];
FILE *image = NULL;
while (fread(buffer, sizeof(BYTE), 1, card) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd0 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if (jpeg_num > 0)
{
fclose(image);
}
sprintf(filename, "%03i.jpeg", jpeg_num);
image = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), 1, image);
jpeg_num++;
}
else
{
fwrite(buffer, sizeof(BYTE), 1, image);
}
}
fclose(image);
fclose(card);
return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
如果(argc!=2)
{
printf(“用法/恢复图像\n”);
返回1;
}
文件*card=fopen(argv[1],“r”);
如果(卡==NULL)
{
printf(“错误\n”);
返回1;
}
int jpeg_num=0;
typedef uint8_t字节;
字节缓冲区[512];
字符文件名[10];
文件*image=NULL;
while(fread(缓冲区,sizeof(字节),1,卡)=1)
{
如果(缓冲区[0]==0xff&&buffer[1]==0xd0&&buffer[2]==0xff&&buffer[3]&0xf0)==0xe0)
{
如果(jpeg_num>0)
{
fclose(图像);
}
sprintf(文件名,“%03i.jpeg”,jpeg\u num);
image=fopen(文件名,“w”);
fwrite(缓冲区,大小(字节),1,图像);
jpeg_num++;
}
其他的
{
fwrite(缓冲区,大小(字节),1,图像);
}
}
fclose(图像);
信用卡;
返回0;
}
CS50使用地址消毒剂(-fsanize=address
)编译程序,对吗?如果是这样,您应该收到如下信息:
ASAN:DEADLYSIGNAL
=================================================================
==4179==错误:地址消毒器:未知地址0x000000000000上的SEGV(pc 0x7f280eabf92e bp 0x000000000001 sp 0x7fffc6e02bd0 T0)
==4179==该信号是由读取内存访问引起的。
==4179==提示:地址指向零页。
#写入(/lib/x86\u 64-linux-gnu/libc.so.6+0x7f92d)中的0 0x7f280eabf92d
#1 0x7f281020107f位于主/../a.c:45中
#2个0x7f280ea61b96,位于libc\u start\u main(/lib/x86\u 64-linux-gnu/libc.so.6+0x21b96)中
#3 0x7f2810200c79在_开始(/…/a+0xc79)
AddressSanitizer无法提供其他信息。
摘要:AddressSanitizer:SEGV(/lib/x86_64-linux-gnu/libc.so.6+0x7f92d)在_IO_fwrite中
==4179==中止
(这是来自gcc
而不是clang
,但是clang
的地址消毒剂应该给出类似的结果。)
所以您尝试从地址0读取。这可能是NULL
或初始化的指针。我们甚至知道它发生在第45行对fwrite
的调用中
有两个指针被传递到fwrite
,buffer
和image
buffer
是一个自动分配的数组,因此它是一个有效的指针<另一方面,代码>图像
初始化如下:
FILE*image=NULL;
在调用fwrite
失败之前,是否可能从未更改?对这很糟糕。如果通过调试器运行代码,它应该会在发生segfault的准确行上停止(这可能不是错误所在的同一行,但如果您在该点检查某些变量的值,您应该能够从上下文中找出它。)fread(缓冲区,大小(字节),1,卡)
仅读取一个字节,但您正在检查缓冲区中的其他字节。始终从fread
捕获返回值,以便知道要写入多少。fwrite(buffer,sizeof(BYTE),1,image)可以/将针对此代码中的NULL
图像文件指针触发。如果If子句至少未满足一次,image
将为null,并且该代码调用未定义的行为。感谢您的帮助!我了解问题所在,但在编写之前我应该在哪里/如何更改它?抱歉,我只是不知道我需要添加什么:/