2012-04-10 54 views
5

我想在PHP擴展中創建並返回一個數組數組。根據我的理解,我應該使用emalloc()爲數組元素分配空間,但我不明白的是何時適合釋放它。我有一個類似於此的PHP函數:何時在PHP擴展中釋放內存?

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]); 
    } 
} 

我應該在哪裏釋放爲pt分配的內存?

回答

6

在這種情況下,您不必。當你返回的變量被銷燬時,它的內存被釋放。既然你正在返回一個數組,那麼當時數組中的所有元素都會被銷燬(更確切地說,當數組被刪除時,它們的引用計數會減少,只有當他們沒有其他引用時他們被釋放)。

您可以通過調用zval_ptr_dtor手動減少zval的引用計數。當其引用計數達到0時,這也將釋放它的內存。

從技術上講,數組變量由HashTable支持。當變量被銷燬時,哈希表也被銷燬。通過這個,與調用HashTable相關聯的「析構函數回調」也被調用,每個哈希表元素都作爲參數。當您調用array_init時,它還會創建一個包含zval_ptr_dtor作爲析構函數的散列表。

另請注意,您在這裏的兩個地方撥打電話emalloc。第一個是明確的,另一個是通過MAKE_STD_ZVAL。第一個是不必要的,但是如果你使用它,你應該在你的函數返回之前調用efree否則它的內存泄漏是因爲它沒有像PHP變量那樣的任何自動內存管理機制。

+0

我正在調用'array_init(pt [i]);'在'MAKE_STD_ZVAL()'後面,忘記將它添加到示例中。所以,如果我理解正確,我根本不應該調用'emalloc()',因爲'MAKE_STD_ZVAL()'負責分配內存,並且當它的引用計數到達零時內存被取消分配(並且應該發生當它超出PHP的範圍時,如果它只被引用一次)。 – rid 2012-04-10 18:01:38

+0

@Radu是的,'MAKE_STD_ZVAL'分配(與'emalloc')zval。然而,你第一次調用'emalloc'並不是分配一個zval,而是分配10個zval *的數組,這與thibg不同。像'actual'說的那樣,你可以使用一個局部變量,或者你可以完全拋棄這個數組,並且這樣做:'{zval * zv; MAKE_STD_ZVAL(ZV); add_index_double(zv,0,1); add_index_zval(return_value,i,zv); }'。 – Artefacto 2012-04-10 18:23:59

1

沒有必要分配在這種情況下使用emalloc內存,只需使用zval *pt[10]或將其降低到可重複使用的單zvalMAKE_STD_ZVAL將處理所有內存(DE)分配和引用計數的東西。