2010-12-08 20 views
2
#include <stdio.h> 
int main() 

{ 

    int *p = (int *)malloc((100*sizeof(int))); 

    p++; 

    free(p); 

/* do something */ 

return 0; 

} 

質問:Cの質問()

  1. 位置p + 1から始まるメモリをmalloc関数が0x1000のを返した場合、解放されたメモリは、Aと仮定すると、0x1004からだろうと言う(無料となります4バイト整数)?

  2. は(あなたがアドレスをP--を行うと、使用しない限り)0x1000番地から4バイト(malloc関数が0x1000のを返した場合)使用可能ではないという事実

+0

あなたの書式が修正されました。コードの書式を正しく設定する方法については、編集ヘルプをお読みください。 –

+1

あなたの質問に直接関係しないヒントについては、(1)Cでは 'malloc'からの返答をキャストしないでください。これは" stdlib.h "を含まない例。 32ビットマシンから64ビットに移行すると、コードが失敗することがあります。 (2)「main」の署名を「改革」しないでください。 Cの 'int main()'と 'int main(void)'は同じではありません。 –

答えて

0

から離れて、このコードでありanypitfallsですこのコードは動作しません。mallocまたは同様の関数によって割り当てられたポインタを解放することはできますが、割り当てられたメモリ範囲の一部を解放することはできません。

12

これは未定義の動作です。malloc()から取得したとおり、正確に同じポインタをfree()に渡す必要があります。あなたのコードで何かが起こる可能性があります - ヒープが破損する可能性があります。

このように考えてください。 free()にはパラメータが1つしかないため、そのパラメータから正確に何をマークするかを推測する必要があります。 「メモリを節約する」方法はありません。それはすべてを解放する(それに必要な控除は非常に時間がかかります)か、何か悪いことが起こります。あなたは何もしないでください。ただしないでください。

1

pはもはやmalloc()で割り当てられたブロックのアドレスではないので、free()呼び出しは失敗します。

+0

必ずしも失敗するとは限りません。ひそかにヒープを破損する可能性があり、後でそれほど気づかないでしょう。 – sharptooth

+0

これは上記で提案された 'sharptooth'のような未定義の動作です。 free()は失敗しません。 – steve

+0

@steve:多分それは失敗するでしょう。 – sharptooth

0

ちょっと私は、GCCの上にこのコードを試してみました、それはで停止:

*** glibc detected *** ./a.out: free(): invalid pointer: 0x0829600c *** 
======= Backtrace: ========= 
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x7be591] 
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x7bfde8] 
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x7c2ecd] 

だからあなたの最初の答えごとにあなたが次のメモリ位置を解放することはできません。 と2番目の質問の場合: とp - を実行しない限り4バイトは使用できません。このコードは、次のメモリ位置の内容を変更しないと、 -

+0

"この特定のC++実装"は必ずしも "これが正解です"という意味ではありません。その実装に対する正解ですが、 "C++"の言語ではありません。 –

0

標準ではこの動作は "未定義"ですが、実際には何も解放されません。 その理由は、mallocが割り当てたチャンクのリストを保持するのは、それぞれのチャンクがで始まり、のアドレスで識別されるからです。 p + 1がそのリストにないため、無料でチャンクが見つかるので、何もしません。