1
int *a = malloc(40);
int *b;
b=a;
if( *some conditions* )
free(a);
// I know that 'a' has been allocated this chunk of memory X times
// and free(a) has been called less than X times.

その状態が分からないので、'a' が解放されたかどうかはわかりません! では、「b」、つまり「a」が解放されたかどうかを確認するにはどうすればよいでしょうか。

4

4 に答える 4

5

free動的に割り当てられたメモリへのポインターに対する後続の呼び出しが害を及ぼさないことを確認したい場合はNULL、そのポインターに割り当てる必要があります。理由(強調を追加):

free() 関数は、ptr が指すメモリー空間を解放します。このメモリー空間は、malloc()、calloc()、または realloc() への以前の呼び出しによって返されたものでなければなりません。それ以外の場合、または free(ptr) が以前に呼び出された場合、未定義の動作が発生します。ptr が NULL の場合、何も実行されません。

bポインターが常に他のポインターが指している同じオブジェクトを参照するようにしたい場合は、代わりにポインターにa変えることができます(使用する必要があるたびに逆参照します)。ba

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

int main() {
    /* dynamically allocate some memory */
    int *a = malloc(40);
    /* b is a pointer to a pointer to an int */
    int **b;
    /* make b point to a */
    b = &a;
    if ( 1 ) {
        /* free memory and assign NULL to the pointer */
        free(a);
        a = NULL;
    }
    /* nothing bad will happen when we dereference b now */
    printf("%p\n", *b);
    /* nothing bad will happen when we free the memory region
       where the pointer b points to points to */
    free(*b);
}

メモリリークに関する別のこと。メモリを二重に解放しても、メモリ リークは発生しません。その場合、未定義の動作に遭遇し、その場合、何かが起こる可能性があります. 自分のものではないメモリ領域にアクセスしてはならないという理由だけで(もう)(cf、この素晴らしい投稿を参照)。代わりに、動的に割り当てられたメモリのブロックへの参照を失うと、メモリ リークが発生します。例えば:

/* allocate some memory */
int *a = malloc(40);
/* reassign a without free-ing the memory before : you now have leaked memory */
a = malloc(40);
于 2013-05-10T07:09:26.187 に答える
1

最良の選択肢は、同じ場所を指している 2 つのポインターを持たないことです。これらは個別に解放されます。
しかし、それが本当に必要な場合は、参照カウントが必要です。

次のコードは、非常に単純な参照カウント メカニズムを実装しています。
データに 2 番目のポインターを割り当てるときは、 を使用clone_xして参照カウントをインクリメントする必要があります。
解放するたびに を使用するfree_xと、一度だけ解放されます。

このコードはマルチスレッドセーフではないことに注意してください。コードがマルチスレッドの場合、アトミック操作が必要であり、その使用方法には細心の注意を払う必要があります。

struct x {
    int refcount;
    int payload;
};
struct x *create_x(int payload) {
    struct x *newx = malloc(sizeof(*newx));
    if (!newx) return NULL;
    newx->payload = payload;
    newx->refcount = 1;
    return newx;
}
void clone_x(struct x *myx) {
    myx->refcount++;
}
void free_x(struct x *oldx) {
    oldx->refcount--;
    if (oldx->refcount == 0) {
         free(oldx);
    }
}
于 2013-05-10T08:14:57.343 に答える