2013-12-18 15 views
3

我看了一些關於SO的其他問題,但他們都沒有解決類似的問題。函數沒有及時釋放

我有一個函數,它對數組進行排序(使用堆排序)並計算中位數。堆排序例程已直接從Numerical Recipies中獲取。

我是calloc ing和free在中值函數中有一個數組,但free似乎沒有及時釋放空間。下面是一些代碼來說明我的意思:

int calcMedian(int n1, int n2, int *dat) 
{ 
    int ii, npt; 
    int *inparr, retval; 

    npt = n2 - n1 + 1; /* Number of elements in array */ 
    inparr = calloc(npt+1, sizeof(*inparr)); 

    for(ii = n1; ii <= n2; ii++) 
     inparr[ii-n1+1] = dat[ii]; /* ii-n1+1 because heapsort function likes arrays to 
           start from 1 */ 

    heapsortInt(npt, inparr); /* The error isn't here, function has been previously 
           debugged. Sorting is in-place.*/ 
    if (npt % 2) 
     retval = inparr[(npt+1)/2]; 
    else 
     retval = (inparr[npt/2]+inparr[npt/2+1])/2; 

    free(inparr); 
    return(retval); 
} 

功能heapsortInt已經相當徹底調試和其他幾個地方的使用是沒有問題的。現在,我把我的功能calcMedian在一個循環中,像這樣:

for(ii = 0; ii < maxval; ii++) { 
    index = ii * maxpt; 
    med1 = calcMedian(index, index+npt1[ii]-1, data1+index); 
    med2 = calcMedian(index, index+npt2[ii]-1, data2+index); 
} 

,其中相關的變量定義如下:

int *data1, *data2; 
int *npt1, *npt2; 

data1 = calloc(maxval * maxpt, sizeof(*data1)); 
data2 = calloc(maxval * maxpt, sizeof(*data2)); 

npt1 = calloc(maxval, sizeof(*npt1)); 
npt2 = calloc(maxval, sizeof(*npt2)); 

所以基本上,我路過一個大陣列的不同部分爲calcMedian和獲取返回必要的中值。

問題:calcMedian似乎在碰到第二個函數調用時會崩潰。我跑了通過Valgrind的,而這也正是它告訴我:

Invalid read of size 4 
at 0x43F67E: calcMedian /* Line no. pointing to calloc in calcMedian */ 
by 0x4416C9: main /* Line no pointing to second call of calcMedian */ 
Address 0x128ffdc0 is 6,128 bytes inside a block of size 110,788 free'd 
at 0x4A063F0: free 
by 0x43F728: calcMedian /* Line no. pointing to free in calcMedian */ 
by 0x4416C9: main /* Line no pointing to first call of calcMedian */ 

這是free有問題嗎?我是否free ing和calloc太頻繁?我不知道從哪裏開始調試。任何幫助將是美好的!

免責聲明:具有實際代碼的計算機無法訪問互聯網。我儘可能準確地複製了導致問題的代碼。如果有任何缺失的分號等是我的錯,那在原始代碼中肯定不存在。

編輯:修正了一些抄寫錯誤。我會嘗試儘快獲得原始代碼,但是從我看過他們兩個現在看來這很好。

+1

'free'總是釋放 「及時」。沒有一個真正的[SSCCE](http://sscce.org),這裏很難給出任何具體的建議... –

+2

你的問題是mots可能是一個索引超出界限。 'index + npt1 [ii] -1'或者另一個可能計算的是一個無限制的內存地址,它偶然指向有效但最近釋放的內存。注意:使用堆棧數組而不是'calloc',除非你的數組必須超出分配它的範圍或者這些數組是多兆字節大。 –

+0

你可能搞砸了內存,如果元數據損壞,'free'也可能變得不可靠。 – Devolus

回答

3

問題是調用calcMedian。

您正在添加索引兩次,一次在調用中,然後在calcMedian中。

它應該是這樣的:

med1 = calcMedian(index, index+npt1[ii]-1, data1); 
med2 = calcMedian(index, index+npt2[ii]-1, data2); 
+0

似乎合理。所以剩下的問題是:爲什麼Valgrind(顯然)不報告由此產生的越界訪問?哦,它是如何導致錯誤報告,*是*被報告? –

+1

Shucks,就是這樣!我現在覺得自己像個白癡。感謝你的幫助! – Kitchi

+0

@OliCharlesworth - 我認爲發生的事情是因爲我傳遞的初始索引,數組在中間的某個地方開始,並在陣列超出邊界時報告錯誤。所以我只能在'calcMedian'循環中看到它。 – Kitchi