2014-07-06 108 views
1

我在写一个比较文件大小的方法(比如任何比较方法)。 这里是我的方法(我用void *作为参数,因为程序的其它部分需要它):fseek() - 访问冲突读取

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,我知道这一点,因为如果我以同样的方式查找,就在fopen之后,它可以正常工作。

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

谢谢。

+1

你为什么使用'void *'? –

+0

@EdHeal我使用void *因为我有一个泛型方法来比较来自不同类型,整数,双精度,文件等等的东西... – shoham

回答

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); 

然后,每个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; 

那么你可以使用只有两个系统调用(而不是四个)。

+0

我每次都犯这个错误!不敢相信我以前没有注意到它。非常感谢你。 – shoham