Ниже приведена созданная мной тестовая функция (для PHP 7.1).
PHP_FUNCTION(tsc_test3)
{
zend_string *cnA;
zend_class_entry *ceA;
// $ret = new ClsA();
cnA = zend_string_init("ClsA", 4, 0);
ceA = zend_fetch_class(cnA, ZEND_FETCH_CLASS_DEFAULT);
zend_string_release(cnA);
object_init_ex(return_value, ceA);
// $ret->propA = $ret;
zval objA;
ZVAL_COPY(&objA, return_value);
zend_update_property(ceA, return_value, "propA", 5, &objA);
zval_ptr_dtor(&objA);
return;
}
Как предлагается в комментарии, он возвращает циклический объект ClsA
.
Ниже приведена тестовая PHP-программа для функции.
<?php
class ClsA {
public $propA = 1;
}
$x = tsc_test3();
echo "DUMP1 ----\n";
var_dump($x);
for ($i = 0; $i < 10; $i++) {
echo "Memory usage: ". memory_get_usage(). "\n";
$x = tsc_test3();
}
echo "DUMP2 ----\n";
var_dump($x);
$x->propA = null;
echo "DUMP3 ----\n";
var_dump($x);
Вот вывод кода PHP.
DUMP1 ----
object(ClsA)#1 (1) {
["propA"]=>
*RECURSION*
}
Memory usage: 351336
Memory usage: 351392
Memory usage: 351448
Memory usage: 351504
Memory usage: 351560
Memory usage: 351616
Memory usage: 351672
Memory usage: 351728
Memory usage: 351784
Memory usage: 351840
DUMP2 ----
object(ClsA)#11 (1) {
["propA"]=>
*RECURSION*
}
DUMP3 ----
object(ClsA)#11 (1) {
["propA"]=>
NULL
}
Результат var_dump()
выглядит нормально, но использование памяти постоянно увеличивается.
Когда я использую ZVAL_COPY_VALUE
вместо ZVAL_COPY
, использование памяти не увеличивается, но выдает странный вывод в DUMP3.
DUMP3 ----
*RECURSION*
Может быть, функция возвращает поврежденный объект.
Может кто-нибудь сказать мне, что не так в функции расширения?
Edit1: Сразу после публикации вопроса я заметил, что memory_get_usage(true)
не увеличивается. Это ошибка, которую я сделал?
Edit2: следующая программа PHP (чистый PHP, без расширения) показывает увеличение использования памяти. Это ошибка PHP или я что-то неправильно понимаю? Я использую PHP 7.1.28.
<?php
class ClsA {
public $propA = 1;
}
for ($i = 0; $i < 10; $i++) {
echo "Memory usage: ". memory_get_usage(). "\n";
$x = new ClsA();
$x->propA = $x;
}