开发者

Array as class member and refcounting

开发者 https://www.devze.com 2023-03-31 04:23 出处:网络
There is something that confuses me. Let there be a class member Foo::$bar, which has to be initialized as an empty array in the

There is something that confuses me. Let there be a class member Foo::$bar, which has to be initialized as an empty array in the constructor. If I do that (via zend_update_property), its refcount is increased (from 1, which it gets after alloc + array_init, to 2). It is obvious why this happens, since from zend_update_property's perspective, it gets a variable from somone in the outside world, and so 开发者_StackOverflowit is right to ++ it.

But in this particular case, the array being initialized in the constructor, it does not need a refcount of 2, 1 is right, since it's used only by the object (yet).

So I thought I will Z_DELREF_P() it. And it worked. Until I started valgrind, which was reporting:

==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

which happens when the engine destroys the object (when the object runs out of scope - the destructor is also called).

So it looks like the ZE really needs the refcount to be 2. All other tests I've written work fine, no memleaks, no segfaults whatsoever.

Still I am a little bit confused: WHY does it need it be higher than (from my understanding) it should be?


@hakre's question made me think.

The explanation is the following: when the ZE destroys the object, it also destroys (zval_ptr_dtor) each property of the object. So it is right to have a refcount of 1 after the destructor was called, which is what I have currently, since I also call zval_ptr_dtor on that specific property decreasing its refcount from 2 to 1.

The ZE will take care of the rest.

0

精彩评论

暂无评论...
验证码 换一张
取 消