我正在编写一个比较文件大小的方法(类似于任何比较方法)。
这是我的方法(我使用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()时,它会崩溃,并在调试器中显示“访问冲突读取”。
这两个文件在我调用方法之前都被正确地打开了,并且不是NULL,我知道这一点,因为如果我以相同的方式查看,就在打开之后,它就工作了。
为什么这不起作用,我该怎么解决?
谢谢。

最佳答案

只是一个猜测:您正在为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;
}

不要忘记,用户代码永远不会取消对aFILE(这是一个不透明的隐藏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;

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

关于c - fseek()-访问冲突阅读,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24593813/

10-11 21:59
查看更多