2

私はこのコードで遊んでいました:

#include <stdlib.h>
#include <stdio.h>

void function(int *p){
    free(p);
}

int main(){
    int *i = calloc(3, sizeof(int));
    function(i);
    i[0] = 'a';
    printf("%c\n", i[0]);
    return 0;
}

エラーが発生することを期待していましたが、代わりに「a」が出力されました。「a」の割り当てが解除された場合、なぜ出力されるのでしょうか。main()の場合、function(int * p)で何が起こるかは効果がありますか?(可能であれば、その'p'ポインターに何が起こるかを説明してください)

同じ関数にこれら2つがあるとします。

int *a = malloc(...);
int *b = a;

どちらも同じメモリを指していますが、それを解放する必要がある場合は、両方を解放する必要がありますか、それとも一方だけを解放する必要がありますか?(可能であれば理由をもう一度説明してください)

4

4 に答える 4

5

それは未定義の動作です。ポインターを解放すると、割り当てられたメモリを上書きできることが OS に通知されます。記憶はまだそこにあります.. より良い言葉がないため. しかし、何かが起こる可能性があります..それは今あなたのために出力するかもしれません.別のプログラムがそのメモリ位置に書き込んだので、別の文字または数字である可能性もあります..何かが起こる可能性があります.

あなたの最後の質問.. a と b は、アドレスの単なる記号名です。そのアドレスで無料で電話をかけることは重要free(a)ですfree(b)

于 2012-11-25T16:14:56.757 に答える
3

あなたは幸運なので、「a」が表示されます。これは未定義の動作です。現在「割り当て解除」されており、つまり、(メモリの場所) は「上書き」のフラグが立てられています。

于 2012-11-25T16:16:07.877 に答える
3

メモリをヒープに戻しましたが、メモリはまだ再利用されていません。そのため、メモリの内容が同じままで、まだ使用されているかのように読み書きできる場合があります。

ただし、メモリが解放されたままの状態がいつまで続くかは保証されていないため、解放済みのメモリは決して使用しないでください。

2 番目の部分a = malloc(...); b = aでは、両方の変数がまったく同じメモリを指しています。これは1バイトにすぎないfree()ため、正確に1 回行う必要があります。そうしないと、二重の解放が発生し、ヒープが破損する可能性があります。

@SSHThis の質問の更新:

free(a)メモリをヒープに戻すだけです。aまたは変更しませんb。メモリが解放されたかどうかに関係なく、チェックif(a)または評価は true になります。またはを null にif(b)設定した場合にのみ、メモリが解放されたかどうかにかかわらず、チェックは false と評価されます。ab

したがってfree(a)、 とif(a)は独立した操作です。それらは互いに影響しません。

a = malloc(10); /* assuming malloc doesn't return NULL */
if (a) {
    /* will be true, memory is NOT freed */
}

free(a);
if (a) {
    /* will be true, although memory is freed */
}

a = malloc(10); /* assuming malloc doesn't return NULL */
a = NULL;
if (a) {
    /* will NOT be true, although memory is NOT freed */
}
于 2012-11-25T16:17:00.770 に答える
2

あなたのコードは間違っていますが、エラーが発生するということは、何かが間違っていることをチェックしていることを意味します。C には、間違っていてもチェックされないことがたくさんあります。これは通常、チェックを実行するとパフォーマンスが低下するか、チェックするのが非常に難しいためです。解放されたメモリへのアクセスは、その 1 つです。valgrind のようなツールを使用してプログラムを実行すると、この種の問題がより多く報告されますが、プログラムの実行速度は大幅に低下します。

valgrind からの出力は次のとおりです。

==19080== Invalid write of size 4
==19080==    at 0x8048468: main (main.c:11)
==19080==  Address 0x403b028 is 0 bytes inside a block of size 12 free'd
==19080==    at 0x4006EED: free (vg_replace_malloc.c:366)
==19080==    by 0x8048434: function (main.c:5)
==19080==    by 0x8048463: main (main.c:10)
==19080== 
==19080== Invalid read of size 4
==19080==    at 0x8048472: main (main.c:12)
==19080==  Address 0x403b028 is 0 bytes inside a block of size 12 free'd
==19080==    at 0x4006EED: free (vg_replace_malloc.c:366)
==19080==    by 0x8048434: function (main.c:5)
==19080==    by 0x8048463: main (main.c:10)
==19080== 
于 2012-11-25T16:20:46.463 に答える