Php 数组作为类成员和引用计数

Php 数组作为类成员和引用计数,php,php-internals,Php,Php Internals,有件事使我困惑。让我们有一个班级成员 Foo::$bar,必须在 构造器。如果我这样做(通过zend\u update\u属性),它的refcount是 增加(从alloc+array_init后得到的1增加到2)。它是 很明显为什么会发生这种情况,因为从zend\u update\u属性的角度来看,它得到了一个 来自外部世界的somone的变量,因此它是正确的 但在这种特殊情况下,数组在 构造函数,它不需要refcount为2,1是正确的,因为它是 仅由对象使用(尚未) 所以我想我会Z\u D

有件事使我困惑。让我们有一个班级成员
Foo::$bar
,必须在 构造器。如果我这样做(通过
zend\u update\u属性
),它的refcount是 增加(从alloc+
array_init
后得到的1增加到2)。它是 很明显为什么会发生这种情况,因为从
zend\u update\u属性的角度来看,它得到了一个
来自外部世界的somone的变量,因此它是正确的

但在这种特殊情况下,数组在 构造函数,它不需要refcount为2,1是正确的,因为它是 仅由对象使用(尚未)

所以我想我会
Z\u DELREF\u p()
it。它成功了。直到我开始 valgrind报道:

==4538== Invalid read of size 4
==4538==    at 0x822D3C6: _zval_ptr_dtor (zend.h:385)
==4538==    by 0x823C1FF: _zval_ptr_dtor_wrapper (zend_variables.c:189)
==4538==    by 0x824E1A1: zend_hash_destroy (zend_hash.c:529)
==4538==    by 0x826655A: zend_object_std_dtor (zend_objects.c:45)
==4538==    by 0x8266A28: zend_objects_free_object_storage 
(zend_objects.c:126)
==4538==    by 0x826C43D: zend_objects_store_del_ref_by_handle_ex 
(zend_objects_API.c:220)
==4538==    by 0x826C0AC: zend_objects_store_del_ref 
(zend_objects_API.c:172)
==4538==    by 0x823BD77: _zval_dtor_func (zend_variables.c:52)
==4538==    by 0x822B99B: _zval_dtor (zend_variables.h:35)
==4538==    by 0x822D463: _zval_ptr_dtor (zend_execute_API.c:443)
==4538==    by 0x823C1FF: _zval_ptr_dtor_wrapper (zend_variables.c:189)
==4538==    by 0x824E518: zend_hash_apply_deleter (zend_hash.c:614)
==4538==  Address 0x44c1718 is 8 bytes inside a block of size 20 free'd
当引擎销毁对象时会发生这种情况(当对象超出范围时,也会调用析构函数)

所以看起来ZE真的需要refcount为2。所有其他 我写的测试很好,没有内存泄漏,没有任何错误

但我还是有点困惑:为什么它需要高于
(据我的理解)应该是吧?

@hakre的问题让我思考

解释如下:当ZE销毁对象时,它也会销毁(
zval\u ptr\u dtor
)对象的每个属性。因此,在调用析构函数之后,refcount为1是正确的,这就是我目前所拥有的,因为我还对该特定属性调用了
zval\u ptr\dtor
,将其refcount从2减少到1


ZE将处理其余部分。

您是否想过,如果构造函数范围结束,一个引用计数将减少?