【问题标题】:Segmentation fault in comparing the second byte of two files比较两个文件的第二个字节时出现分段错误
【发布时间】:2015-02-21 11:54:51
【问题描述】:

我正在测试命令 fread() 和 fseek,并编写了一个程序来比较两个程序的第二个字节。程序在指示的行(最后一个 fread())处给出了分段错误。

int main(int argc, char** argv)
{
    FILE *file1, *file2;
    long size1, size2;
    long size1a, size2a;
    char *name1, *name2;
    char *temp1, *temp2;

    if (argc != 3)
    {
        cout<<"Enter two file names"<<endl;
        exit(1);
    }

    name1 = argv[1];
    name2 = argv[2];

    //open files
    file1 = fopen(name1, "r");
    file2 = fopen(name2, "r");

    //get file size
    fseek(file1, 0, SEEK_END);
    size1 = ftell(file1);
    rewind(file1);

    fseek (file2,0,SEEK_END);
    size2 = ftell(file2);
    rewind(file2);

    fseek(file1,1,SEEK_SET);
    fseek(file2,1,SEEK_SET);
    cout<<"1"<<endl; //----cout worked
    fread(temp1,1,1,file1);
    cout<<"2"<<temp1<<endl; //---cout worked. 2nd byte of file1 was printed.
    fread(temp2,1,1,file2); //SEGMENTATION FAULT AT THIS LINE

    if(*temp1==*temp2)
        cout<<"same"<<endl;
    else
        cout<<"different"<<endl;    

    return 0;
}

虽然我通过定义更正了程序

char temp1, temp2;

写作

fread(&temp1,1,1,file1);
fread(&temp2,1,1,file2);

我仍然不知道是什么导致了第二个 fread 的 seg 错误,而第一个 fread 运行正确。分段错误的原因可能是什么?

【问题讨论】:

    标签: c++ fread fseek


    【解决方案1】:

    1) 以二进制模式打开文件`fp = fopen(name, "rb");

    2) 查看文件打开结果if(fp != NULL)

    3) 为数据分配内存:char *temp1; 是不够的,它只是指针,你需要这样的东西:

      temp = (char*) malloc(sizeof(char) * N); // N number of bytes
    

    编辑:

    4) 不要忘记关闭文件(即使它不是导致分段错误的原因)。

    我只是进行了更改,以下代码可以正常工作:

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    
    int main(int argc, char** argv)
    {
        FILE *file1, *file2;
        long size1, size2;
        long size1a, size2a;
        long greater;
        char *name1, *name2;
        char *temp1, *temp2;
        // memory allocation (two lines added)
        temp1 = (char*) malloc(sizeof(char));
        temp2 = (char*) malloc(sizeof(char));
    
        if (argc != 3)
        {
            cout<<"Enter two file names"<<endl;
            exit(1);
        }
    
        name1 = argv[1];
        name2 = argv[2];
    
        //open files
        file1 = fopen(name1, "rb");
        if(file1 == NULL)
        {
            cout<<"File "<< name1 << " cannot be read" <<endl;
            exit(1);
        }
        file2 = fopen(name2, "rb");
        if(file2 == NULL)
        {
            cout<<"File "<< name2 << " cannot be read" <<endl;
            exit(1);
        }
        //get file size
        fseek(file1, 0, SEEK_END);
        size1 = ftell(file1);
        rewind(file1);
    
        fseek (file2,0,SEEK_END);
        size2 = ftell(file2);
        rewind(file2);
    
        if(size1>size2) greater = size1;
        else greater = size2;
    
        fseek(file1,1,SEEK_SET);
        fseek(file2,1,SEEK_SET);
        cout<<"1"<<endl; //----cout worked
        fread(temp1,1,1,file1);
        cout<<"2"<<temp1<<endl; //---cout worked. 2nd byte of file1 was printed.
        fread(temp2,1,1,file2); //SEGMENTATION FAULT AT THIS LINE
    
        if(*temp1==*temp2)
            cout<<"same"<<endl;
        else
            cout<<"different"<<endl;    
    
        fclose(file1);
        fclose(file2);
        // memory de-allocation (two lines added)
        free(temp1);
        free(temp2);
        return 0;
    }
    

    EDIT2:

    5) 使用后释放内存(又增加了两行)

    【讨论】:

    • “未定义的行为”是很奇怪的事情 :-)
    • 成功了,谢谢!但是我仍然不明白在我的早期版本中,为什么第一个 fread 有效而第二个无效!他们都不应该工作。后来看到你的评论..慢网!谢谢。 :)
    • 也许,在其他计算机编译其他编译器后,第一个 fread 也会导致错误....参见en.wikipedia.org/wiki/Undefined_behavior
    • 也许,第一个错误fread破坏了内存中的某些东西(准备错误),第二个fread只是显示错误
    • “代码没有问题”?您创建了内存泄漏,malloc 不应在 C++ 中使用。在你看到我的回答之后,IIRC 第 3 点也是一个编辑......
    【解决方案2】:

    第一个版本的问题是temp 指针不指向任何东西:

    char *temp1, *temp2;
    ...
    fread(temp1,1,1,file1);
    

    这样,文件中的字符被放置在temp 指针指向的随机位置。

    使用第二个版本,字符放在temp 变量中,这没问题。

    【讨论】:

    • 那么为什么第一个 fread 有效而第二个无效? (在程序的第一个版本中)
    • 很难说,是巧合。未定义的行为难以分析。
    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多