1

私を混乱させるものがあります。Foo::$barコンストラクターで空の配列として初期化する必要があるクラス member があると します。これを ( 経由でzend_update_property) 行うと、refcount が増加します ( alloc +array_initの後に取得する 1 から 2 に)。zend_update_propertyの観点からすると、外の世界の somone から変数を取得し、それを ++ にするのは正しいため、なぜこれが起こるのかは明らかです。

しかし、この特定のケースでは、配列がコンストラクターで初期化されます。2 の refcount は必要ありません。オブジェクトによってのみ使用されるため (まだ)、1 が正しいです。

だからやろうと思っZ_DELREF_P()た。そして、それはうまくいきました。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 にする必要があるようです。私が書いた他のすべてのテストは正常に動作し、memleaks も segfault もまったくありません。

それでも私は少し混乱しています:なぜそれは(私の理解から)あるべきよりも高くする必要があるのですか?

4

1 に答える 1

0

@hakre さんの質問で考えさせられました。

説明は次のとおりです。ZE がオブジェクトを破棄すると、オブジェクトのzval_ptr_dtor各プロパティも破棄 ( ) されます。そのため、デストラクタが呼び出された後に 1 の refcount を持つことは正しいことです。これは、zval_ptr_dtorその特定のプロパティを呼び出してその refcount を 2 から 1 に減らしているためです。

残りは ZE が処理します。

于 2011-08-25T10:46:58.923 に答える