2014-07-06 71 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