-4

私は、可変数の引数を受け取り、それらすべて、あらゆるタイプの引数を解放する関数を作成するという使命を持っています。可変引数関数を使用して実行しようとしましたが、引数の型がわかりません。

それを行う方法はありますか?

4

1 に答える 1

2

各ポインタをvoid *;として扱います。それをに渡しfree()ます:

void free_anything(void *arg1, ...)
{
    va_list args;
    void *vp;
    free(arg1);
    va_start(args, arg1);
    while ((vp = va_arg(args, void *)) != 0)
        free(vp);
    va_end(args);
}

呼び出しの例:

free_anything(p1, p2, p3, p4, (void *)0);

別の設計では、解放する引数の数を最初の引数として渡します。

free_everything(4, p1, p2, p3, p4);

代替関数の実装は演習として残されています...


カウンター ( free_everything()) を使用した設計の方がおそらく優れていることに注意してください。次のように、関数で複数の割り当てをクリーンアップする関数を作成できます。

void memory_intensive(int size)
{
    int *p1 = malloc(size * sizeof(*p1));
    char *p2 = malloc(size * 32);
    struct wotnot *p3 = malloc(sizeof(*p3));
    struct onemore *p4 = malloc(size * sizeof(*p4));
    struct later *p5 = 0;
    struct muchlater *p6 = 0;

    if (some_condition(p1, p3, size))
    {
        p5 = malloc(size * sizeof(*p5));
        ...
    }
    if (another_condition(p2, p4, size))
    {
        p6 = malloc(size * sizeof(*p6));
        ...
    }

    free_everything(6, p1, p2, p3, p4, p5, p6);
}

これにより、割り当てられているかどうか(または他の割り当てが失敗したかどうp5か) に関係なく、1 回の関数呼び出しですべての割り当てられたメモリが解放されます。p6しかし、これは限界を広げています。ただし、このような設計では、最初のヌル ポインターで停止しないことが重要です。リストの後半に非ヌル ポインターがある場合に備えてです。

于 2013-02-07T07:47:43.200 に答える