如果文件大小未知,如何检测分段错误的原因? [英] How to detect cause of segmentation fault if size of file is unknown?

查看:48
本文介绍了如果文件大小未知,如何检测分段错误的原因?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我试图从文件中读取内容,该文件以512字节的块存储.我知道为什么会发生分段错误,但是由于我不知道JPEG文件的大小,所以我不知道在哪里遇到问题.调试器在调用fread之后确实会停止,尽管我不知道为什么会这么做.

运行调试器时,循环可能运行40次以上,然后由于分段错误而崩溃.

这是到目前为止我正在使用的代码:缓冲区已被分配为512的大小

  int计数器= 0;char * fileName =(char *)malloc(sizeof(int));//sprintf(fileName,"%03i.jpg"计数器);FILE * img = NULL;while(feof(p)== 0){fread(buffer,sizeof(char),512,p);如果(buffer [0] == 0xff&&&&&& buffer [2] == 0xff&&(((buffer [3]& 0xf0)== 0xe0))//检查前四个字节是否匹配{如果(img == NULL){sprintf(fileName,"%03i.jpg"计数器);img = fopen(fileName,"w"));fwrite(buffer,sizeof(char),512,img);}别的{计数器++;sprintf(fileName,"%03i.jpg"计数器);img = fopen(fileName,"w"));fwrite(buffer,sizeof(char),512,img);}}别的{//继续写入现有文件如果(img == NULL){继续;}别的{fwrite(buffer,sizeof(char),512,img);}}如果(feof(p)> 0){fclose(p);fclose(img);免费(文件名);免费(缓冲区);返回0;} 

解决方案

您只需要一次读取512个字节.

然后,您循环检查定界符,并在看到分隔符时更改输出文件.

由于定界符在512字节边界上是对齐,因此,您只想一次读取512字节-不多也不少.

正如我在最高评价中提到的那样,已经有很多答案.但是,我回答了类似的问题,并在下面生成了以下调试代码:

  #include< stdio.h>#include< stdlib.h>#include< stdint.h>#include< stdbool.h>bool magictag(uint8_t *);整型main(int argc,char * argv []){如果(argc!= 2){fprintf(stderr,用法:./恢复图像\ n");返回1;}FILE *存储卡= fopen(argv [1],"r");如果(!memorycard){fprintf(stderr,无法打开文件\ n");返回2;}int file_no = 0;int b;整数代码= 0;uint8_t buf [1000];FILE * jpeg = NULL;//虽然尚未达到EOF而(1){b = fread(buf,512、1,存储卡);如果(b == 0)休息;int startflg = magictag(buf);如果(startflg){如果(jpeg!= NULL)fclose(jpeg);字符输出文件[50];sprintf(outfile,%03i.jpg",file_no);++ file_no;jpeg = fopen(outfile,"w");如果(jpeg == NULL){fprintf(stderr,"jpg无法创建\ n");代码= 3;休息;}}如果(jpeg!= NULL)fwrite(buf,512,1,jpeg);}如果(jpeg!= NULL)fclose(jpeg);fclose(存储卡);返回码;}布尔magictag(uint8_t * c){bool ret = false;做 {如果(c [0]!= 0xFF)休息;如果(c [1]!= 0xD8)休息;如果(c [2]!= 0xFF)休息;如果((c [3]& 0xF0)!= 0xE0)休息;ret = true;}而(0);返回ret} 

请注意,实际问题在这里:我恢复的图像在CS50 PSET4恢复中不匹配

我没有发布上面的代码,因为OP已经从那里的注释中解决了问题.

Basically I am trying to read from a file, where contents are stored in blocks of 512 bytes. I know why segmentation faults occur but since I dont know the sizes of the JPEG files, I don't know where I am running into the problem. The debugger does stop after calling fread although I have no idea why it does that.

When running the debugger, the loops runs for maybe 40+ times and then it crashes due to segmentation error.

This is the code I am working with so far: THe buffer has been malloc'ed the size of 512

int counter = 0;
char *fileName = (char *) malloc(sizeof(int));
//sprintf(fileName, "%03i.jpg", counter);

FILE *img = NULL;

while(feof(p) == 0)
{
    fread(buffer, sizeof(char), 512, p);

    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3] & 0xf0) == 0xe0)) //checks if the first four bytes match
    {
        if(img == NULL)
        {
            sprintf(fileName, "%03i.jpg", counter);
            img = fopen(fileName, "w");
            fwrite(buffer, sizeof(char), 512, img);
        }
        else
        {
            counter++;
            sprintf(fileName, "%03i.jpg", counter);
            img = fopen(fileName, "w");
            fwrite(buffer, sizeof(char), 512, img);
        }
    }
    else
    {
        //continue writing to existing file
        if(img == NULL)
        {
            continue;
        }
        else
        {
            fwrite(buffer, sizeof(char), 512, img);
        }
    }

    if(feof(p) > 0)
    {
        fclose(p);
        fclose(img);
        free(fileName);
        free(buffer);
        return 0;
    }

解决方案

You only need to read 512 bytes at one time.

And, you loop checking for the delimiters and change the output file when you see one.

Since the delimiters are aligned on a 512 byte boundary, you only want to read 512 bytes at one time--no more and no less.

As I mentioned in my top comments, there are plenty of answers already. But, I responded on a similar question, and produced the following debugged code below:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

bool magictag(uint8_t *);

int
main(int argc, char *argv[])
{

    if (argc != 2) {
        fprintf(stderr, "Usage:./recover image\n");
        return 1;
    }
    FILE *memorycard = fopen(argv[1], "r");

    if (!memorycard) {
        fprintf(stderr, "File cannot be opened\n");
        return 2;
    }

    int file_no = 0;
    int b;
    int code = 0;
    uint8_t buf[1000];

    FILE *jpeg = NULL;

    // While haven't reached EOF
    while (1) {
        b = fread(buf, 512, 1, memorycard);
        if (b == 0)
            break;

        int startflg = magictag(buf);

        if (startflg) {
            if (jpeg != NULL)
                fclose(jpeg);

            char outfile[50];
            sprintf(outfile, "%03i.jpg", file_no);
            ++file_no;

            jpeg = fopen(outfile,"w");
            if (jpeg == NULL) {
                fprintf(stderr, "jpg cannot be created\n");
                code = 3;
                break;
            }
        }

        if (jpeg != NULL)
            fwrite(buf, 512, 1, jpeg);
    }

    if (jpeg != NULL)
        fclose(jpeg);

    fclose(memorycard);

    return code;
}

bool
magictag(uint8_t *c)
{
    bool ret = false;

    do {
        if (c[0] != 0xFF)
            break;
        if (c[1] != 0xD8)
            break;
        if (c[2] != 0xFF)
            break;
        if ((c[3] & 0xF0) != 0xE0)
            break;
        ret = true;
    } while (0);

    return ret;
}

Note that the actual question was here: My recovered images don't match in CS50 PSET4 Recover

I didn't post the above code because that OP already solved the problem from the comments there.

这篇关于如果文件大小未知,如何检测分段错误的原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆