2012-04-02 15 views
3

このエラーは、私が割り当てられた構造体を解放しようとしているときに起きます。構造体がNULLに設定されているためそれを解放している。エラー: "ポインタが解放されていませんでした。"

ここに私の構造体は、その中には本当のポインタである:

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)を書くことができますか? –

+0

「セカンドタイム」が実際にどのように起こるかを示すことができますか?表示されているコードは 'freeTouch()'を一度しか呼び出しません。 – unwind

答えて

3

fはローカル変数です。 free(f)は割り当てられたメモリに影響しますが、f = NULLmyTouchには影響しません。freeTouch(myTouch);です。

ではなく

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

を試してみて、freeTouch(&myTouch)を使用しています。 xが前に割り当てられ、reallocが失敗した場合、メモリが残っている間、あなたはそれNULL作るため、あなたはゴミを作成するため、すべての

+1

含まれているコードが 'freeTouch()'への複数の呼び出しを示していないので、これは問題になることはまずありません。また、 'free(NULL)'は問題ありません。 – unwind

+0

私の元のコードmyTouchとinputCounterはグローバルですが、ヒントを付けて修正しました! void freeTouch(){ if(myTouch!= NULL){ 空き(myTouch); myTouch = NULL; } } –

+1

@unwind:OPには、フリータッチの複数の呼び出しが彼の「...」のどこかにあったと思います。主な問題は、このケースでは 'myTouch = NULL'を設定しなかったことです。 – Zeta

1

まず、

x = realloc(x, size); 

を使用することはありません。

次に、

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

なお、 'free(NULL)'は明確に定義されているので、 '* f!= NULL'をチェックする必要はありません。 –

+0

@OliCharlesworth、あなたは正しいですが、それは私の習慣です – Shahbaz

2

あなたには2つの問題があります。最初に、戻り値を明示的にキャストすることはお勧めできません。mallocまたはreallocプロトタイプ/ヘッダーを含めることを忘れると問題が発生する可能性があります。

第2に、関数内でfを解放すると、ローカルコピーが解放されます。 Cが参照を得るまで、2つの可能性があります。まず、ポインタへのポインタを渡して、それを使用します。

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

をしたり、割り当てることができるので、バックNULLを渡す:

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

あなたは二番目はあなたが合格するかどうかを気にしないことに気づくでしょうNULL - 実質的には何もしていない(関数呼び出し自体以外の)ので、NULLポインタを空けてみることは完全に容認されます。

関連する問題