Zend API: zval_dtor, zval_ptr_dtor

本文详细介绍了 PHP 中 zval 的内存管理机制,重点解析了 zval_dtor 和 zval_ptr_dtor 宏函数的作用及实现原理。通过具体代码展示了如何在不再使用 zval 变量时正确地释放内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 zval_dtor和zval_ptr_dtor是2个宏函数,定义在(zend_variables.h):

#define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_ptr_dtor(zval_ptr) _zval_ptr_dtor((zval_ptr) ZEND_FILE_LINE_CC)
_zval_dtor也是定义在( zend_variables.h ):
ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC);

static inline void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
{
	if (zvalue->type <= IS_BOOL) {
		return;
	}
	_zval_dtor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
}
_zval_dtor_func定义在(zend_variables.c):
ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
{
	switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
		case IS_STRING:
		case IS_CONSTANT:
			CHECK_ZVAL_STRING_REL(zvalue);
			STR_FREE_REL(zvalue->value.str.val);
			break;
		case IS_ARRAY:
		case IS_CONSTANT_ARRAY: {
				TSRMLS_FETCH();

				if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
					zend_hash_destroy(zvalue->value.ht);
					FREE_HASHTABLE(zvalue->value.ht);
				}
			}
			break;
		case IS_OBJECT:
			{
				TSRMLS_FETCH();

				Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
			}
			break;
		case IS_RESOURCE:
			{
				TSRMLS_FETCH();

				/* destroy resource */
				zend_list_delete(zvalue->value.lval);
			}
			break;
		case IS_LONG:
		case IS_DOUBLE:
		case IS_BOOL:
		case IS_NULL:
		default:
			return;
			break;
	}
}

_zval_ptr_dtor定义在(zend_execute_API.c):

ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
{
	zval *zv = *zval_ptr;

#if DEBUG_ZEND>=2
	printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
#endif
	Z_DELREF_P(zv);
	if (Z_REFCOUNT_P(zv) == 0) {
		TSRMLS_FETCH();

		if (zv != &EG(uninitialized_zval)) {
			GC_REMOVE_ZVAL_FROM_BUFFER(zv);
			zval_dtor(zv);
			efree_rel(zv);
		}
	} else {
		TSRMLS_FETCH();

		if (Z_REFCOUNT_P(zv) == 1) {
			Z_UNSET_ISREF_P(zv);
		}

		GC_ZVAL_CHECK_POSSIBLE_ROOT(zv);
	}
}
好了,结果就是一点 zval_ptr_dtor会调用zval_dtor来释放内容。所以不在使用某个zval变量的时候记得及时清除掉。


转载于:https://my.oschina.net/jackin/blog/173579

PHP Warning: PHP Startup: Unable to load dynamic library 'bz2.so' (tried: /usr/lib64/php/modules/bz2.so (/usr/lib64/php/modules/bz2.so: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/bz2.so.so (/usr/lib64/php/modules/bz2.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'pdo.so' (tried: /usr/lib64/php/modules/pdo.so (/usr/lib64/php/modules/pdo.so: undefined symbol: _zval_ptr_dtor), /usr/lib64/php/modules/pdo.so.so (/usr/lib64/php/modules/pdo.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_mysql.so' (tried: /usr/lib64/php/modules/pdo_mysql.so (/usr/lib64/php/modules/pdo_mysql.so: undefined symbol: _zval_copy_ctor_func), /usr/lib64/php/modules/pdo_mysql.so.so (/usr/lib64/php/modules/pdo_mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'bz2' (tried: /usr/lib64/php/modules/bz2 (/usr/lib64/php/modules/bz2: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/bz2.so (/usr/lib64/php/modules/bz2.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'calendar' (tried: /usr/lib64/php/modules/calendar (/usr/lib64/php/modules/calendar: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/calendar.so (/usr/lib64/php/modules/calendar.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'ctype' (tried: /usr/lib64/php/modules/ctype (/usr/lib64/php/modules/ctype: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/ctype.so (/usr/lib64/php/modules/ctype.so: cannot open shared object fil
最新发布
03-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值