7

戻り値を格納するために別の関数に渡されるバッファーを動的に割り当てる C の関数があります。次のダミーの例のようなもの:

void other_function(float in, float *out, int out_len) {
    /* Fills 'out' with 'out_len' values calculated from 'in' */
}

void function(float *data, int data_len, float *out) {
    float *buf;
    int buf_len = 2 * data_len, i;
    buf = malloc(sizeof(float) * buf_len);

    for (i = 0; i < data_len; i++, data++, out++) {
        other_function(*data, buf, buf_len);
        /* Do some other stuff with the contents of buf and write to *out */
    }
    free buf;
}

functionは、多次元配列 (正確には NumPy の gufunc カーネル) に対してイテレータによって呼び出されるため、同じ値で何百万回も呼び出されdata_lenます。バッファの作成と破棄を何度も繰り返しているのは無駄に思えます。私は通常、バッファの割り当てを を呼び出す関数に移動しfunction、ポインタをそれに渡しますが、それを直接制御することはできないため、不可能です。代わりに、次のことを検討しています。

void function(float *data, int data_len, float *out) {
    static float *buf = NULL;
    static int buf_len = 0;
    int i;
    if (buf_len != 2 * data_len) {
        buf_len = 2 * data_len;
        buf = realloc(buf, sizeof(float) * buf_len); /* same as malloc if buf == NULL */
    }
    for (i = 0; i < data_len; i++, data++, out++) {
        other_function(*data, buf, buf_len);
        /* Do some other stuff with the contents of buf and write to *out */
    }
}

つまり、割り当てたメモリを直接解放することはありません。メモリは後続の呼び出しで再利用され、プログラムが終了するまでそこに残ります。これは正しいことではないように思えますが、割り当てられるメモリの量が常に少なくなるため、それほど悪いことでもありません。私は心配しすぎですか?これに対するより良いアプローチはありますか?

4

2 に答える 2