2012-04-10 10 views
5

PHP拡張モジュールに配列の配列を作成して返したいと思います。私が理解するところでは、emalloc()を使用して配列要素の領域を割り当てる必要がありますが、私が理解できないのは、解放することが適切なときです。私はこれに似たPHP機能を持っている:PHP拡張モジュールのメモリを解放するのはいつですか?

私は ptに割り当てられたメモリを解放する必要があり
PHP_FUNCTION(test) 
{ 
    int i; 
    zval **pt = emalloc(sizeof(zval*) * 10); 

    array_init(return_value); 

    for (i = 0; i < 10; ++i) { 
     MAKE_STD_ZVAL(pt[i]); 
     array_init(pt[i]); 
     add_index_double(pt[i], 0, 1); 
     add_index_zval(return_value, i, pt[i]); 
    } 
} 

答えて

6

この場合、そうする必要はありません。あなたが返す変数が破壊されると、そのメモリは解放されます。配列を返すので、配列のすべての要素もその時までに破棄されます(より正確には、配列が削除されると参照カウントが減少します。彼らは解放される)。

zval_ptr_dtorを呼び出すことによって、zvalの参照カウントを手動で減らすことができます。参照カウントが0になると、メモリも解放されます。

技術的には、配列変数にはHashTableが付いています。変数が破棄されると、ハッシュテーブルも破棄されます。これにより、HashTableに関連付けられた「デストラクタコールバック」が、各ハッシュテーブル要素を引数として1回呼び出されます。 array_initを呼び出すと、デストラクタ関数としてzval_ptr_dtorのハッシュテーブルも作成されます。

また、emallocへの電話は2か所にあります。最初は明示的で、もう1つはMAKE_STD_ZVAL経由です。最初のものは不要ですが、使用する場合は、PHP変数のような自動メモリ管理機構に関連付けられていないので、関数が返される前にefreeを呼び出す必要があります。

+0

私は 'MAKE_STD_ZVAL()'の直後に 'array_init(pt [i]);'を呼び出して、例に追加するのを忘れてしまいました。したがって、正しく理解すれば 'MAKE_STD_ZVAL()'はメモリの割り当てを担当し、参照カウントが0になったときにメモリの割り当てが解除されるので(emalloc()は呼び出さないでください) PHPで範囲外になったとき、それが一度しか参照されていない場合)。 – rid

+0

@Raduはい、 'MAKE_STD_ZVAL'は(emalloc'で)zvalも割り当てます。しかし、最初の 'emalloc'の呼び出しでは、zvalを割り振りません。同じzibgではない10個のzval *の配列を割り当てています。 'actual'と同様に、ローカル変数を使用することもできますし、配列を完全に破棄して、次のようにすることもできます:' {zval * zv; MAKE_STD_ZVAL(zv); add_index_double(zv、0、1); add_index_zval(return_value、i、zv); } '。 – Artefacto

1

(デ)の割り当てと参照カウントのもの、この場合にはemallocを使用してメモリを割り当てるだけzval *pt[10]を使用するか、またはMAKE_STD_ZVALは、すべてのメモリを処理する、単一の再利用可能なzvalにそれを軽減する必要はありません。

関連する問題