2015-02-04 9 views
1

что на самом деле является правильным способом вернуть динамически распределенный zval из функции c и зарегистрировать его автоматический dtor?PHP 7 return dynamic alloc zval right way

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 показывает, что ecalloc от php_test_fcn() утечки.

Любые советы?

p.s .: код извлекается из проекта и, возможно, не на 100% прав - я пытался его минимизировать.

UPDATE:

ecalloc на Params - это фактическая утечка.

Если я это сделать:

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 на указателе **?

+1

Вы должны преуменьшать его версии предполагается работать правильно. Это так? – Mehraban

+1

обновленный вопрос - с локальными vars он работает - так что мой 'ecalloc' на указателе' ** 'кажется проблемой –

ответ

0

хорошо ответил себе: 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(&params[i]); 
    //efree(params[i]); 
} 

efree(params); 
zval_ptr_dtor(&return_value); 

 Смежные вопросы

  • Нет связанных вопросов^_^