2012-04-10 39 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)分配和引用计数的东西。