1

楽しみのために (そして C プログラミングの練習のために)、次のことを行う次のコードを書きました。

  • メモリ割り当ての追跡システムとして機能します
  • 関数呼び出しで動的に割り当てられたすべてのメモリを解放します

コードは次のとおりです。

typedef enum _OpMode {
    OM_APPEND,
    OM_DESTROY
} OP_MODE;

void refOp(void *ptr, OP_MODE mode) {
    /* contains static array of pointers and provides an interface to that
       array */

    static void **references = NULL;
    static int size = 0;
    static int reset = 0;

    if (reset) {
        reset = 0;
        references = NULL;
        size = 0;
    }

    switch (mode) {
        case OM_APPEND:
            //add a pointer to reference array
            references = (void**) realloc(references, sizeof(void*) * (size + 1));
            references[size++] = ptr;
            break;
        case OM_DESTROY:
            //free memory at all pointers kept in reference array
            for (int i = 0; i < size; i++) {
                free(references[i]);
                references[i] = NULL;
            }
            free(references);
            reset = 1;
            break;
        default:
            printf("Invalid enum value '%d' passed as mode.\n", mode);
            break;
    }
}

void refDestroyAll() {
    //Wrapper function
    refOp(NULL, OM_DESTROY);
}

void *myAlloc(void* ptr, size_t size) {
    /* Allocates memory and stores pointer copy in reference array */
    void *tmp_ptr;
    tmp_ptr = realloc(ptr, size);
    refOp(tmp_ptr, OM_APPEND);
    return tmp_ptr;
}

アイデアは、myAlloc()代わりに、mallocまたはrealloc動的にメモリを割り当てるために使用することです。そしてrefDestroyAll()、 で作成されたすべてのメモリを解放するために使用しmyAlloc()ます。

いくつかのテストを行ったところ、機能しているように見えますが、何か重要なものが欠けていると感じずにはいられません。このコードは実際に意図したとおりに機能しますか? または、呼び出し時にメモリ リークが発生していますrefDestroyAll()か?

4

1 に答える 1

1

セグメンテーション違反を引き起こす可能性のあるバグがあります。realloc()与えられたものと同じポインタを返す可能性があります。その場合、配列に2回追加します。free関数を呼び出すと、同じポインタを2回解放しようとするため、セグメンテーション違反エラーが発生します。

また、リセットパラメータがある理由がわかりません。この場合、単に参照とサイズを0に設定してみませんOM_DESTROYか?ポインタを解放した直後は、常にポインタをNULLに設定することをお勧めします。

于 2012-07-30T04:51:42.913 に答える