2012-04-02 43 views
3

這個錯誤總是被觸發,當我試圖釋放我分配的結構第二次,它不應該,因爲結構設置爲NULL後,我解放它。錯誤:「指針被釋放未被分配」在c

這裏是我的結構與它裏面沒有真正的指針:

typedef struct{ 
     int frame; 
     double timestamp; 
     int identifier; 
     int state; 
     int unknown1; 
     int unknown2; 
     mtVector normalized; 
     float size; 
     int unknown3; 
     float angle; 
     float majorAxis; 
     float minorAxis; 
     mtVector unknown4; 
     int unknown5[2]; 
     float unknown6; 
    }Touch; 

準系統主要功能:

int main(){ 
    Touch *myTouch = NULL; 
    int inputCounter = 0; 
    //whenever a touch is recognized: 
    ... 
    myTouch = (Touch*)realloc(myTouch,sizeof(Touch)*(inputCounter++)); 
    ... 
    // everything works fine until: 
    freeTouch(myTouch); 
} 

void freeTouch(Touch *f){ 
    if(f != NULL){ 
     free(f); 
     f = NULL; 
    } 
} 

任何人有一個想法?

+0

該代碼應該正常工作。你能寫一個[最小的測試用例](http://sscce.org)嗎? – 2012-04-02 10:46:40

+0

你可以展示「第二次」實際發生的情況嗎?所示的代碼只調用'freeTouch()'一次。 – unwind 2012-04-02 10:49:57

回答

3

f是一個局部變量。 free(f)將影響分配的內存,但f = NULLfreeTouch(myTouch);中的myTouch沒有影響。

嘗試

void freeTouch(Touch **f){ 
    if(*f != NULL){ 
     free(*f); 
     *f = NULL; 
    } 
} 

來代替,而freeTouch(&myTouch)

+1

這不太可能是問題,因爲包含的代碼不會顯示多次調用'freeTouch()'。另外,'free(NULL)'沒問題,所以沒有必要保護它。 – unwind 2012-04-02 10:49:32

+0

在我原來的代碼myTouch和inputCounter是全局的,但你的提示我修好了! (myTouch!= NULL){ free(myTouch); myTouch = NULL; } } – 2012-04-02 10:53:09

+1

@unwind:我猜OP在他的'...'的某個地方有多次對'freeTouch'的調用。主要的問題是他沒有在這種情況下設置myTouch = NULL。 – Zeta 2012-04-02 10:55:02

1

首先,切勿使用

x = realloc(x, size); 

,因爲如果x之前分配和realloc失敗了,你讓它NULL而內存仍然存在,因此,您創建的垃圾。

其次,

void freeTouch(Touch *f); 

得到由值的指針,因此不能改變指針本身。所以你的f = NULL;是無效的。您需要將代碼更改爲:

int main(){ 
    Touch *myTouch = NULL, temp; 
    int inputCounter = 0; 
    //whenever a touch is recognized: 
    ... 
    temp = realloc(myTouch,sizeof(*temp) * (inputCounter++)); 
    if (temp == NULL) 
     /* handle error */ 
    myTouch = temp; 
    ... 
    // everything works fine until: 
    freeTouch(&myTouch); 
} 

void freeTouch(Touch **f){ 
    if(f != NULL && *f != NULL){ 
     free(*f); 
     *f = NULL; 
    } 
} 

旁註:這是一個好主意,用realloc(同樣地malloc)是這樣的:

x = realloc(count * sizeof(*x)); 

沒有必要投下輸出或realloc。此外,sizeof(*x)允許您不要每次重複x的類型。

+2

順便說一句,沒有必要檢查'* f!= NULL',因爲'free(NULL)'是明確定義的。 – 2012-04-02 10:50:06

+0

@OliCharlesworth,你說得對,但這只是我的習慣 – Shahbaz 2012-04-02 11:01:10

2

你有兩個問題。首先,從mallocrealloc明確投出返回值並不是一個好主意。如果您忘記包含原型/標題,則會導致問題。

其次,釋放f內部功能釋放本地拷貝。在C獲得參考之前,有兩種可能性。首先一個指針傳遞到指針和使用:

void freeTouch (Touch **pF){ 
    if (*pF != NULL){ 
     free (*pF); 
     *pF = NULL; 
    } 
} 
: 
freeTouch (&myTouch); 

或傳回空,因此你可以分配:

void *freeTouch (Touch *f){ 
    free (f); 
    return NULL; 
} 
: 
myTouch = freeTouch (myTouch); 

您會發現,第二個不關心你是否在傳遞NULL - 嘗試釋放NULL指針是完全可以接受的,因爲它實際上是一個無操作(除了函數調用本身)。

相關問題