- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑2:根据我最初的问题,它是通过
的帮助解决的Weather Vane
我们发现了对指针基础知识的严重误解。一旦我查看了指针信息,我就解决了我的段错误。谢谢大家
操作:
** 目标是,给定一个 card.raw 文件,使用 jpeg 签名恢复所有 jpeg,并假设一旦找到一个 jpeg,所有其他 jpeg 都会连续出现,直到文件末尾。该文件采用 FAT 512 字节 block 格式。 **
正如标题所说,我不确定我正在做什么来获得段错误。我尝试过使用 valgrind 和 gcd 进行调试,但由于我是编码新手,我找不到段错误的根源。我承认,尝试破译这些调试函数的输出被证明比我预期的更加神秘。
此外,我还搜索了具有类似段错误的其他人,但我发现的其他人(尤其是在本网站上)的错误源 self (我认为)没有的代码中的另一个错误。
这让我发疯,因为看起来我已经正确创建了一个缓冲区,确保文件始终在不将它们困在条件语句中的情况下打开和关闭,并且正确地利用 fwrite 创建了正确 block 大小的 jpeg .
我感谢所提供的所有帮助。
编辑:
根据评论者的要求,这是我的 valgrind 输出:
~/workspace/pset4/recover/ $ valgrind --leak-check=full ./recover card.raw
==26277== Memcheck, a memory error detector
==26277== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26277== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==26277== Command: ./recover card.raw
==26277==
==26277== Invalid read of size 1
==26277== at 0x42DC1F: write_jpeg (recover.c:79)
==26277== by 0x9A904008211C1099: ???
==26277== by 0x82104489A502E0F: ???
==26277== by 0x2104082104082103: ???
==26277== by 0x408210408210407: ???
==26277== by 0x821040821040820: ???
==26277== by 0x9304082104082103: ???
==26277== by 0x21840021840048: ???
==26277== by 0x4208104248208481: ???
==26277== by 0x13F0E30705210447: ???
==26277== by 0x13E8E0CA918D0902: ???
==26277== by 0xD384118482262983: ???
==26277== Address 0x821040821040821 is not stack'd, malloc'd or (recently) free'd
==26277==
==26277==
==26277== Process terminating with default action of signal 11 (SIGSEGV)
==26277== General Protection Fault
==26277== at 0x42DC1F: write_jpeg (recover.c:79)
==26277== by 0x9A904008211C1099: ???
==26277== by 0x82104489A502E0F: ???
==26277== by 0x2104082104082103: ???
==26277== by 0x408210408210407: ???
==26277== by 0x821040821040820: ???
==26277== by 0x9304082104082103: ???
==26277== by 0x21840021840048: ???
==26277== by 0x4208104248208481: ???
==26277== by 0x13F0E30705210447: ???
==26277== by 0x13E8E0CA918D0902: ???
==26277== by 0xD384118482262983: ???
==26277==
==26277== HEAP SUMMARY:
==26277== in use at exit: 1,136 bytes in 2 blocks
==26277== total heap usage: 2 allocs, 0 frees, 1,136 bytes allocated
==26277==
==26277== LEAK SUMMARY:
==26277== definitely lost: 0 bytes in 0 blocks
==26277== indirectly lost: 0 bytes in 0 blocks
==26277== possibly lost: 0 bytes in 0 blocks
==26277== still reachable: 1,136 bytes in 2 blocks
==26277== suppressed: 0 bytes in 0 blocks
==26277== Reachable blocks (those to which a pointer was found) are not shown.
==26277== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==26277==
==26277== For counts of detected and suppressed errors, rerun with: -v
==26277== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
// prototypes
void write_jpeg(int count, FILE *file, uint8_t buffer[]);
int main(int argc, char *argv[]) {
// ensure correct argument usage
if (argc != 2) {
fprintf(stderr, "Error. Correct usage: ./recover [infile]\n");
return 1;
}
// open infile
FILE *file = fopen(argv[1], "r");
// ensure can open file
if (file == NULL) {
fprintf(stderr, "Error, could not open file\n");
return 2;
}
// initializes bool variable that signals start of jpegs
bool start = false;
// buffer for file block
uint8_t buffer[512];
// loop to find the start of the series of jpegs
while (!start) {
// read FAT blocks into buffer
fread(&buffer, 1, 512, file);
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff
&& (buffer[3] & 0xf0) == 0xe0) {
start = true;
fseek(file, -4, SEEK_CUR);
memset(buffer, 0x00, 512);
}
}
// count for number of jpegs
int count = 0;
// loop to create jpegs
while ((fread(&buffer, 1, 512, file)) == sizeof(buffer)) {
write_jpeg(count, file, buffer);
}
fclose(file);
return 0;
}
// writes into a new file until the start of another jpeg
void write_jpeg(int count, FILE *file, uint8_t buffer[]) {
// creates filenames for jpegs
char file_name[8];
sprintf(file_name, "%03i.jpg", count);
// opens file to write to
FILE *img = fopen(file_name, "w");
if (img == NULL) {
fprintf(stderr, "Error: couldnt create jpg file\n");
return;
}
// bool for end condition
bool end = false;
while (!end) {
// ends if reaches new jpeg signature
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff
&& (buffer[3] & 0xf0) == 0xe0) {
end = true;
fseek(file, -4, SEEK_CUR);
memset(buffer, 0x00, 512);
count++;
} else {
// read the next block into buffer
fread(&buffer, 1, 512, file);
// write the buffer into the new file
fwrite(&buffer, 1, 512, img);
}
}
fclose(img);
}
最佳答案
在 write_jpeg
函数中,这是不正确的:
fread(&buffer,
fread
函数需要一个指向要写入的空间的指针。但是,您提供了一个指向空间的指针,其中存储了指向该空间的指针。
应该是fread(buffer,
)。你在fwrite
中犯了同样的错误,在main
中也犯了同样的错误(但在这种情况下,由于实现细节,您可以逃脱惩罚)。
此外,如果count
达到1000
,就会出现缓冲区溢出。 %03i
printf 说明符表示 3
位的最小值,而不是最大值。
关于CS50 pset4 段错误recover.c >> 我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45342095/
我是一名优秀的程序员,十分优秀!