gpt4 book ai didi

php - 尝试在PHP扩展中写一个内部函数,结果报内存泄漏,找了半天也没找到原因

转载 作者:太空宇宙 更新时间:2023-11-04 08:02:36 26 4
gpt4 key购买 nike

最近看了一本关于PHP扩展的书,准备写一个函数,函数原型(prototype)如下:

array_groupBy(string $key, array $input, $forget = false):array

该函数的作用是根据分组的值对应的$key$input进行分组,$forget 表示group后面的数组是否需要删除$key$clourse为可调用类型,如果存在则为$key对应的值code> 将传递给闭包函数内部,闭包函数返回新的字符串作为新数组的键,像这样:

enter image description here

和输出:

enter image description here

和源代码

PHP_FUNCTION(array_groupBy){

zend_string *key;
zval *input, *val, *key_zval;
zval group_zval, copy, retval, copy_key_zval;
zend_bool forget = 0, have_callback = 0;
HashTable *ht;
zend_fcall_info fcall_info = empty_fcall_info;
zend_fcall_info_cache fcall_info_cache = empty_fcall_info_cache;
int ret;

ZEND_PARSE_PARAMETERS_START(2, 4)
Z_PARAM_STR(key)
Z_PARAM_ARRAY(input)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(forget)
Z_PARAM_FUNC(fcall_info, fcall_info_cache)
ZEND_PARSE_PARAMETERS_END();

if(ZEND_NUM_ARGS() > 3){
have_callback = 1;
}

ht = (HashTable *)emalloc(sizeof(HashTable));
zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);

ZEND_HASH_FOREACH_VAL(Z_ARR_P(input), val){

ZVAL_COPY(&copy, val);

key_zval = zend_symtable_find(Z_ARR_P(val), key);
if(have_callback){
ZVAL_COPY(&copy_key_zval, key_zval);
fcall_info.retval = &retval;
fcall_info.params = &copy_key_zval;
fcall_info.no_separation = 0;
fcall_info.param_count = 1;
ret = zend_call_function(&fcall_info, &fcall_info_cache);
zval_ptr_dtor(&copy_key_zval);
if(ret != SUCCESS || Z_TYPE(retval) == IS_UNDEF){
zend_array_destroy(ht);
RETURN_NULL();
}
ZVAL_STR(&copy_key_zval, Z_STR(retval));
}else{
ZVAL_STR(&copy_key_zval, zend_string_dup(Z_STR_P(key_zval), 0));
}
convert_to_string(&copy_key_zval);
//GC_REFCOUNT(Z_STR(copy_key_zval)--;

if(zend_hash_exists(ht, Z_STR(copy_key_zval))){
group_zval = *zend_hash_find(ht, Z_STR(copy_key_zval));
}else{
array_init(&group_zval);
zend_hash_add_new(ht, Z_STR(copy_key_zval), &group_zval);
}

if(forget){
SEPARATE_ARRAY(&copy);
zend_symtable_del(Z_ARR(copy), key);
}
add_next_index_zval(&group_zval, &copy);

}ZEND_HASH_FOREACH_END();

RETURN_ARR(ht);
}

结果是正确的,但是报告“检测到总共 3 次内存泄漏”,当我打开 GC_REFCOUNT(Z_STR(copy_key_zval))-- 时,报告“检测到总共 1 次内存泄漏”。因为我不知道如何调试上面的代码,导致我找了半天也找不到原因,谁能帮帮我?

php_version
PHP 7.2.0-dev (cli)(内置:2017 年 3 月 31 日 10:47:40)(NTS DEBUG)
版权所有 (c) 1997-2017 The PHP Group
Zend Engine v3.2.0-dev,版权所有 (c) 1998-2017 Zend Technologies

最佳答案

copy_key_zval 中的字符串添加到数组后,您并没有释放它。当它最初被创建时,它的引用计数为 1,当它被添加到数组中时,它的引用计数为 2; PHP 假定您的函数卡在它上面,直到您另行通知它。使用后需要通过zval_ptr_dtor()释放其内容。

同样,您不会在分离后在 copy 中释放数组。

关于php - 尝试在PHP扩展中写一个内部函数,结果报内存泄漏,找了半天也没找到原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45100513/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com