PHP 7 return 动态分配 zval 正确的方式
PHP 7 return dynamic alloc zval right way
从 c 函数 return 动态分配 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()
,它似乎注册了一个 auto-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(¶ms[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(¶ms[i]);
}
//efree(params);
zval_ptr_dtor(&return_value);
它不会泄漏 - 因为局部变量。
知道 **
指针上的 ecalloc 有什么问题吗?
ok 自己回答了 :D
问题是 **
指针。
最终代码 - 做到了:
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(¶ms[i]);
//efree(params[i]);
}
efree(params);
zval_ptr_dtor(&return_value);
从 c 函数 return 动态分配 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()
,它似乎注册了一个 auto-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(¶ms[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(¶ms[i]);
}
//efree(params);
zval_ptr_dtor(&return_value);
它不会泄漏 - 因为局部变量。
知道 **
指针上的 ecalloc 有什么问题吗?
ok 自己回答了 :D
问题是 **
指针。
最终代码 - 做到了:
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(¶ms[i]);
//efree(params[i]);
}
efree(params);
zval_ptr_dtor(&return_value);