【发布时间】:2021-10-15 15:58:46
【问题描述】:
在 CS50 课程的第 4 周尝试从 raw 文件中恢复 jpgs 时,我遇到了这个 seg fault 错误,我不明白它是为什么或如何引起的,我只能说根据valgrind 行 110 导致此问题
我是 c 语言的新手
int main(int argc, char *argv[])
{
// check if one command arg is passed
if (argc > 2 )
{
printf("Usage: ./recover image\n");
return 1;
}
// try to open file to read from
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
BYTE bytes[512];
int x =0 ;
char num[10];
FILE* output =NULL;
while (fread(&bytes, 512, 1, file) == 1)
{
// first step create file name
sprintf(num, "%03i.jpg",x);
// check for start of jpg file
if (bytes[0]==0xff && bytes[1] ==0xd8 && bytes[2]== 0xff && (bytes[3] & 0xf0) == 0xe0 )
{
printf("Found file {%i}", x);
output = fopen(num , "w");
fwrite(&bytes ,512 ,1 ,output);
x++;
}
else
{
fwrite(&bytes , 512 , 1 , output);
}
}
return 0;
}
valgrind 的输出
==12934== Invalid read of size 4
==12934== at 0x4A1C521: fwrite (iofwrite.c:37)
==12934== by 0x4014CA: main (recover.c:110)
==12934== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==12934==
==12934==
==12934== Process terminating with default action of signal 11 (SIGSEGV)
==12934== Access not within mapped region at address 0x0
==12934== at 0x4A1C521: fwrite (iofwrite.c:37)
==12934== by 0x4014CA: main (recover.c:110)
==12934== If you believe this happened as a result of a stack
==12934== overflow in your program's main thread (unlikely but
==12934== possible), you can try to increase the size of the
==12934== main thread stack using the --main-stacksize= flag.
==12934== The main thread stack size used in this run was 8388608.
==12934==
==12934== HEAP SUMMARY:
==12934== in use at exit: 472 bytes in 1 blocks
==12934== total heap usage: 2 allocs, 1 frees, 4,568 bytes allocated
==12934==
==12934== LEAK SUMMARY:
==12934== definitely lost: 0 bytes in 0 blocks
==12934== indirectly lost: 0 bytes in 0 blocks
==12934== possibly lost: 0 bytes in 0 blocks
==12934== still reachable: 472 bytes in 1 blocks
==12934== suppressed: 0 bytes in 0 blocks
==12934== Rerun with --leak-check=full to see details of leaked memory
==12934==
==12934== For lists of detected and suppressed errors, rerun with: -s
==12934== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
zsh: segmentation fault valgrind ./recover card.raw
【问题讨论】:
-
你能解释一下this
-
@G.M.我也想过,但这不可能。请注意,
bytes衰减为BYTE*和&bytes变为*(BYTE[512])并转换为void*始终到相同的地址,所以问题必须是别的东西。 -
我会尝试使用地址清理程序运行它以获得更好的错误描述。类似:
gcc -O2 -g -fsanitize=address,undefined main.c -o test && ./testvalgrind 这里不是很有帮助。 -
真正的问题应该是:这条线
output = fopen(num , "w");成功了吗?另请注意else声明它可以尝试写入未打开的文件。 -
将代码分割成更小的块。请注意,您也在泄漏文件描述符。
标签: c cs50 null-pointer