22

たとえば、ポインター newPtr を作成し、malloc(some size) を使用してから、後で同じポインターで malloc(some size) を使用するとします。何が起こるのですか?次に、最初のブロックと同じサイズの 2 番目のメモリ ブロックを作成していますか? newPtr は同じアドレスを指していますか?

例:

int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = malloc(10 * sizeof(int));
4

4 に答える 4

26

プログラムにメモリ リークが発生します。の最初の値newPtrが失われ、それができなくなりますfree

次に、最初のブロックと同じサイズの 2 番目のメモリ ブロックを作成していますか?

はい。最初のオブジェクトとは異なる、2 番目のオブジェクトを割り当てています。

newPtr は同じアドレスを指していますか?

いいえ。オブジェクトは異なるため、アドレスも異なります。

于 2013-10-17T19:24:17.237 に答える
11

malloc実際には同じポインターで使用していません。あなたはポインタをまったく与えていませんmallocmalloc常に新しいメモリを割り当てます。したがって、変数の割り当ての場合と同じことが起こります。

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));
于 2013-10-17T19:25:29.377 に答える
4

これらのステートメントは malloc on を使用していませんnewPtr

このステートメントnewPtr = malloc(10 * sizeof(int));により、次の操作が行われます。

  1. sizeof(int)評価されます。
  2. その値は 10 倍されます。
  3. mallocが呼び出され、その製品がそれに渡されます。
  4. malloc値を返します。
  5. その値は に割り当てられnewPtrます。

ご覧のとおり、ステップ 3 では、newPtrまったく関与していません。mallocやった後だけnewPtr絡む。

2 度目に呼び出すとmalloc、 で何かをしていることを知る方法がありませんnewPtr。新しい領域を割り当てて、その領域へのポインタを返すだけです。次に、その新しいポインタが に割り当てられnewPtr、 にあった古い値が消去されnewPtrます。

その時点で、古い値が何であったかを知る方法はありません。領域は解放されていないため、まだ割り当てられていますが、その領域へのポインタがありません。

于 2013-10-17T19:27:52.580 に答える
3

「同じポインターでmallocを使用」していません。malloc()(スペースを割り当ててそのスペースへのポインターを返す)を呼び出し、その戻り値を同じポインターオブジェクトに割り当てています。(mallocそれ自体は、返された結果で何をしようとしているのかわかりません。)

2 番目の割り当ては、他の割り当てと同様に、以前に保存された値を置き換えます。

つまり、別の場所に保存しない限り、最初に割り当てられたメモリのチャンクへのポインタがなくなります。これはメモリ リークです。

さらに、 によって返された結果mallocがヌル ポインターであるかどうかを常にチェックし、ヌル ポインターである場合は何らかの修正措置を講じる必要があります。最も単純なケースでは、エラー メッセージを出力してプログラムを終了するだけかもしれません。呼び出しが成功したと仮定して、(存在しない) 割り当てられたメモリを使用しようとするべきではありません。malloc(これはあなたの質問には関係ありませんが、特にほとんどのコンテキストで割り当ての失敗はまれであるため、見落としがちです。)

于 2013-10-17T19:25:36.253 に答える