【问题标题】:PHP 7 return dynamic alloc zval right wayPHP 7 以正确的方式返回动态分配 zval
【发布时间】:2015-04-03 14:59:48
【问题描述】:

从 c 函数返回动态分配的 zval 并将其注册为自动 dtor 的正确方法是什么?

zval * php_test_fcn() {
    zval * t;
    t = ecalloc(sizeof(zval), 1);
    ZVAL_LONG(t, 1);
    return t;
}

另一方面,我打电话:

zval **params = NULL;
int arg_num=5;
int x=0;
params = ecalloc(arg_num, sizeof(zval));
for(x=0; x<arg_num; x++) {
    params[i]=php_test_fcn();
}

///SOME MORE code
/// call_user_function .....
call_user_function(EG(function_table), NULL, func, &return_value, arg_num, *params TSRMLS_CC);
//cleanup
for(x=0; x<arg_num; x++) {
    zval_ptr_dtor(params[i]);
}
efree(params);     

在 PHP 7 之前,我使用:MAKE_STD_ZVAL(),它似乎注册了一个自动 dtor。 现在 valgrind 显示来自php_test_fcn()ecalloc 泄漏。

有什么建议吗?

p.s.:代码是从一个项目中提取的,可能不是 100% 正确 - 我试图缩小它。

更新:

params 上的 ecalloc - 是实际的泄漏。

如果我这样做:

zval params[100];
int  i      = 0;
int  arg_num  = lua_gettop(L);

//params = ecalloc(arg_num, sizeof(zval));
if(arg_num >= 100) return 0;

for (i=0; i<arg_num; i++) {     
    //params[i] = php_lua_get_zval_from_lua(L, -(arg_num-i), NULL TSRMLS_CC);
    ZVAL_COPY_VALUE(&params[i], php_lua_get_zval_from_lua(L, -(arg_num-i), NULL TSRMLS_CC));

}

call_user_function(EG(function_table), NULL, func, &return_value, arg_num, params TSRMLS_CC);
php_lua_send_zval_to_lua(L, &return_value TSRMLS_CC);

for (i=0; i<arg_num; i++) {
    zval_ptr_dtor(&params[i]);
}

//efree(params);
zval_ptr_dtor(&return_value);

它不会泄漏 - 因为局部变量。 知道** 指针上的 ecalloc 有什么问题吗?

【问题讨论】:

  • 您应该将其缩小到应该可以正常工作的版本。是这样吗?
  • 更新的问题 - 使用本地变量它可以工作 - 所以我在 ** 指针上的 ecalloc 似乎是问题

标签: php zend-framework php-extension php-7


【解决方案1】:

好的,我自己回答了:D

问题是**pointer。

最终代码 - 做到了:

zval * params = NULL;
zval * t;
int  i      = 0;
int  arg_num  = lua_gettop(L);

params = safe_emalloc(sizeof(zval), arg_num, 0);
//if(arg_num >= 100) return 0;

for (i=0; i<arg_num; i++) {
    //params[i]=ecalloc(1, sizeof(zval));
    //params[i] = php_lua_get_zval_from_lua(L, -(arg_num-i), NULL TSRMLS_CC);
    params[i]=*php_lua_get_zval_from_lua(L, -(arg_num-i), NULL TSRMLS_CC);                      
}


call_user_function(EG(function_table), NULL, func, &return_value, arg_num, params TSRMLS_CC);
php_lua_send_zval_to_lua(L, &return_value TSRMLS_CC);

for (i=0; i<arg_num; i++) {
    zval_ptr_dtor(&params[i]);
    //efree(params[i]);
}

efree(params);
zval_ptr_dtor(&return_value);

【讨论】:

    猜你喜欢
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2010-09-28
    • 2013-05-09
    • 1970-01-01
    • 2015-09-01
    相关资源
    最近更新 更多