fseek() - 访问冲突读取

时间:2014-07-06 07:55:54

标签: c file

我正在编写一种比较文件大小的方法(比如任何比较方法)。 这是我的方法(我使用void *作为参数,因为程序的其他部分需要它):

int compareFileSize(void * p1, void * p2)
{
    int result;
    FILE * f1, *f2;
    f1 = (FILE *)p1;
    f2 = (FILE *)p2;
    fseek(f1, 0, SEEK_END);
    fseek(f2, 0, SEEK_END);
    result = ftell(f1) - ftell(f2);
    fseek(f1, 0, SEEK_SET);
    fseek(f2, 0, SEEK_SET);
    return result;
}

当它到达fseek()时,它会崩溃并说“#34;访问违规读取"在调试器中。 在调用方法之前,这两个文件都是正确的,并且不是NULL,我知道这一点,因为如果我以同样的方式调试,就在fopen之后,它可以工作。

为什么这不起作用,我该如何解决?

感谢。

1 个答案:

答案 0 :(得分:2)

只是猜测:你正在为qsort(3)编写一个比较函数,你传递了一个FILE*指针数组:

FILE* arrfil[5] = { NULL };
arrfil[0] = stdout;
arrfil[1] = fopen("foo1","r");
arrfil[2] = fopen("foo2","r");

等,稍后调用

qsort(arrfil, 5, sizeof(FILE*), compareFileSize);

然后,compare函数的每个const void*参数都是一个指向指针的指针,所以你应该编码

int compareFileSize(const void * p1, const void * p2)
{
    FILE* f1 = *(FILE**)p1;
    FILE* f2 = *(FILE**)p2;
    if (f1 == f2) return 0;
    if (!f1) return 1;
    if (!f2) return -1;
    if (fseek(f1, 0, SEEK_END)) return 1;
    if (fseek(f2, 0, SEEK_END)) return -1;
    result = ftell(f1) - ftell(f2);
    fseek(f1, 0, SEEK_SET);
    fseek(f2, 0, SEEK_SET);
    eturn result;
} 

不要忘记用户代码永远不会取消引用FILE(这是一个不透明的隐藏struct);换句话说,你总是处理FILE* 指针

顺便说一句,如果您正在为某些POSIX系统编码,您可以使用fstat(2)并执行

    struct stat st1 ={0}, st2={0};
    if (fstat(fileno(f1),&st1) return 1;
    if (fstat(fileno(f2),&st2) return -1;
    if (st1.st_size == st2.st_size) return 0;
    if (st1.st_size < st2.st_size) return -1;
    else return 1;

然后你只会使用两个系统调用(而不是四个)。