たとえば、ポインター newPtr を作成し、malloc(some size) を使用してから、後で同じポインターで malloc(some size) を使用するとします。何が起こるのですか?次に、最初のブロックと同じサイズの 2 番目のメモリ ブロックを作成していますか? newPtr は同じアドレスを指していますか?
例:
int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = malloc(10 * sizeof(int));
プログラムにメモリ リークが発生します。の最初の値newPtrが失われ、それができなくなりますfree。
次に、最初のブロックと同じサイズの 2 番目のメモリ ブロックを作成していますか?
はい。最初のオブジェクトとは異なる、2 番目のオブジェクトを割り当てています。
newPtr は同じアドレスを指していますか?
いいえ。オブジェクトは異なるため、アドレスも異なります。
malloc実際には同じポインターで使用していません。あなたはポインタをまったく与えていませんmalloc。malloc常に新しいメモリを割り当てます。したがって、変数の割り当ての場合と同じことが起こります。
int a;
a = 14;
a = 20;
はどうなり14ますか?もうアクセスできません。これmallocは、返されたポインターへの参照がなくなったことを意味するため、メモリリークが発生します。
実際に " with the same pointer" を使用したい場合mallocは、関数に興味があるかもしれませんrealloc:
int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = realloc(newPtr, 10 * sizeof(int)); //*might leak memory*
そのリンクから:realloc「ptrが指すメモリブロックのサイズを変更します。関数は、メモリブロックを新しい場所に移動する場合があります(そのアドレスは関数によって返されます)。」
編集:realloc上記で失敗した場合は NULL を返しますが、が指すメモリnewPtrは解放されないことに注意してください。この回答に基づいて、これを行うことができます:
void *emalloc(size_t amt){
void *v = malloc(amt);
if(!v) {
fprintf(stderr, "out of mem\n");
exit(EXIT_FAILURE);
}
return v;
}
void *erealloc(void *oldPtr, size_t amt){
void *v = realloc(oldPtr, amt);
if(!v) {
fprintf(stderr, "out of mem\n");
exit(EXIT_FAILURE);
}
return v;
}
その後:
int *newPtr;
newPtr = emalloc(10 * sizeof(int));
newPtr = erealloc(newPtr, 10 * sizeof(int));
これらのステートメントは malloc on を使用していませんnewPtr。
このステートメントnewPtr = malloc(10 * sizeof(int));により、次の操作が行われます。
sizeof(int)評価されます。mallocが呼び出され、その製品がそれに渡されます。malloc値を返します。newPtrます。ご覧のとおり、ステップ 3 では、newPtrまったく関与していません。mallocやった後だけnewPtr絡む。
2 度目に呼び出すとmalloc、 で何かをしていることを知る方法がありませんnewPtr。新しい領域を割り当てて、その領域へのポインタを返すだけです。次に、その新しいポインタが に割り当てられnewPtr、 にあった古い値が消去されnewPtrます。
その時点で、古い値が何であったかを知る方法はありません。領域は解放されていないため、まだ割り当てられていますが、その領域へのポインタがありません。
「同じポインターでmallocを使用」していません。malloc()(スペースを割り当ててそのスペースへのポインターを返す)を呼び出し、その戻り値を同じポインターオブジェクトに割り当てています。(mallocそれ自体は、返された結果で何をしようとしているのかわかりません。)
2 番目の割り当ては、他の割り当てと同様に、以前に保存された値を置き換えます。
つまり、別の場所に保存しない限り、最初に割り当てられたメモリのチャンクへのポインタがなくなります。これはメモリ リークです。
さらに、 によって返された結果mallocがヌル ポインターであるかどうかを常にチェックし、ヌル ポインターである場合は何らかの修正措置を講じる必要があります。最も単純なケースでは、エラー メッセージを出力してプログラムを終了するだけかもしれません。呼び出しが成功したと仮定して、(存在しない) 割り当てられたメモリを使用しようとするべきではありません。malloc(これはあなたの質問には関係ありませんが、特にほとんどのコンテキストで割り当ての失敗はまれであるため、見落としがちです。)