【问题标题】:When to free memory in a PHP extension?何时释放 PHP 扩展中的内存?
【发布时间】:2012-04-10 16:45:23
【问题描述】:

我想在 PHP 扩展中创建并返回一个数组数组。据我了解,我应该使用emalloc() 为数组元素分配空间,但我不明白什么时候适合释放它。我有一个类似这样的 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 的内存?

【问题讨论】:

    标签: c php-extension


    【解决方案1】:

    在这种情况下,您不必这样做。当您返回的变量被销毁时,它的内存被释放。由于您要返回一个数组,因此该数组的所有元素也将在那个时候被销毁(更准确地说,当数组被删除时,它们的引用计数会减少,只有到那时它们没有其他引用才会他们被释放了)。

    您可以通过调用 zval_ptr_dtor 手动减少 zval 的引用计数。当它的引用计数达到 0 时,这也会释放它的内存。

    从技术上讲,数组变量由HashTable 支持。当变量被销毁时,哈希表也被销毁。这样,与HashTable 关联的“析构函数回调”也被调用,每个哈希表元素作为参数一次。当你调用array_init时,它还会创建一个以zval_ptr_dtor为析构函数的哈希表。

    另请注意,您在此处的两个地方拨打emalloc。第一个是显式的,另一个是通过MAKE_STD_ZVAL。第一个是不必要的,但如果你使用它,你应该在你的函数返回之前调用efree,否则它的内存泄漏,因为它没有像 PHP 变量那样与任何自动内存管理机制相关联。

    【讨论】:

    • 我在MAKE_STD_ZVAL() 之后调用array_init(pt[i]);,忘记将其添加到示例中。所以,如果我理解正确,我根本不应该调用emalloc(),因为MAKE_STD_ZVAL() 负责分配内存,并且当它的引用计数达到零时内存被释放(当它出来时应该会发生这种情况) PHP 中的范围,如果它只被引用一次)。
    • @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); }
    【解决方案2】:

    在这种情况下,无需使用emalloc 分配内存,只需使用zval *pt[10] 或将其减少为单个可重复使用的zvalMAKE_STD_ZVAL 将处理所有内存(取消)分配和引用计数。

    【讨论】:

      猜你喜欢
      • 2011-11-03
      • 2019-09-05
      • 2014-03-10
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      • 2013-12-12
      • 1970-01-01
      相关资源
      最近更新 更多