2012-02-25 14 views
-2

mallocとgotoの関係に問題があると思います。または、私はそこに起こっているメモリのいくつかの無駄や記憶の破損があると思います。希望、誰かが私に正確なエラーを指摘することができます。 コンパイル時にエラーが出ることはありませんが、私のシニアは間違いがあると主張しています。この機能で何が問題になっていますか?

#define FINISH() goto fini; 

BOOL Do() 
{ 

    BOOL stat; 
    UINT32 ptr; 
    int err; 

    ptr = (UINT32)malloc(1000); 


    free((void*)ptr); 

fini: 
    return stat; 
} 
+15

'の#define FINISH()後藤FINI;'オハイオ州の主は慈悲 – orlp

+3

がgoto' '使用しないでください持っている:あなたは、実際のポインタ型であることをptrを変更すると、ちょうどこれを行います。マクロ内に 'goto'を隠さないでください。 –

+0

このコードはコンパイルされますか?私はそうは思わない。 –

答えて

4

は、ここで私は、コードerr != ERROR_SUCCESSこの関数はメモリリークが発生します

  • にスポット問題です。 freeコールにジャンプします。
  • mallocの戻り値を32ビットの位置に格納しています。これはポータブルな解決策ではありません。 64ビットプラットフォームでは、アドレスを切り捨てるので、プログラムに大混乱が生じます。ここで非ポインタ型を使用する必要がある場合は、size_tを代わりに使用してください(ただし、整数型にポインタを割り当てることをおすすめします)。
  • ローカルstatはここでは明確に割り当てられていません。 err != ERROR_SUCCESSの場合はごみを返送しています。常に値を割り当てる必要があります。最も簡単な方法は、デフォルトを提供することです。
  • あなたはmallocの戻り値をチェックし、潜在的にFun2

に隠されたNULLポインタを渡すここでは、へのポインタを変換している私は

BOOL Do() 
{ 

    BOOL stat = FALSE; 
    size_t ptr = 0; 
    int err; 

    ptr = (UINT32)malloc(1000); 
    err = Fun1(); 

    if (err != ERROR_SUCCESS || ptr == 0) 
     FINISH(); 
    else 
     stat = Fun2(ptr); 

fini: 
    free((void*)ptr); 
    return stat; 
} 
+0

'if'がtrueに評価された場合に' stat'も初期化されないと思います。 – Muggen

+0

'ptr!= 0'チェックは必要ありません:' 0'はヌルポインタに変換され、 'free()'はヌルポインタセーフです – Christoph

+0

@Muggenありがとう、ちょうど最近の編集で修正されました – JaredPar

3

mallocはポインタを返します。あなたは整数へのポインタをキャストしていますが、ポインタと整数は同じ表現を持つ必要はありません。たとえば、ポインタのサイズは64ビットで、整数に収まらない場合があります。

また、オブジェクトstatは、関数で初期化されていないものとして使用することができます。明示的にオブジェクトを初期化しないと、statは宣言の後で不定値を持ちます。

+0

これは正解です。ダウンボッターは説明を気にかけますか? –

+0

@ ErnestFriedman-Hill、 '(UINT32)malloc(1000)'は何をしていると思いますか? –

+0

私の悪い、downvote反転、コメントが削除されました。この1つは私に飛び出さなかった他の多くの問題があります。 –

1

Fun1()ERROR_SUCCESSを返さない場合、ptrは決して解放されません。おそらく、それはあなたの上司が話しているエラーです。

1

を提案し、編集した関数だありませんuint32_tに戻ります。これにより、ポインタ値の上半分が消去されます。

0

何をしても、あなたはそのコードをコンパイルしていません。構文エラーがあります。

if(foo) 
    bar;; 
else 
    baz 

ビルドシステムを確認してください。

0

私の全体的なコメントと、Cで作業するための一般的な経験則...ポインタキャストを行う必要がある場合は、自分自身に質問してください。あなたが正直にポインタキャストを行う必要がある時代は非常にまれです。はるかに一般的なのは、理解に若干のギャップがあり、やっていることややっているべきことがはっきりしていないし、コンパイラの警告を黙らせようとしているために、ポインタキャストを使うときです。

ptr = (UINT32)malloc(1000); 

非常に悪い!この "ポインタ"を使って何かすると、64ビットのplaformで動作すると非常に幸運です。ポインタをポインタ型のままにします。絶対に整数に格納する必要がある場合は、十分に大きいことが保証されているuintptr_tを使用してください。

私はあなたがやろうとしてきたかもしれないと言うだろう:

// Allocate 1,000 32-bit integers 
UINT32 *ptr = (UINT32*)malloc(1000 * sizeof(UINT32)); 

しかしそれさえもがCコード、奇妙なCおよびC++のハイブリッドの貧フォームです。 C++とは異なり、Cであなただけのvoid *を取ることができますし、暗黙的に任意のポインタ型にそれを持って来る:void*にキャスト

// Allocate 1,000 32-bit integers 
UINT32 *ptr = malloc(1000 * sizeof(UINT32)); 

最後に、

free((void*)ptr); 

することは頻繁に署名すること、別の大きな赤い旗であり、彼らは何をしているのか分からない。

free(ptr);