Question about zend_hash_next_index_insert function
Good day!
I want to modify array (array of arrays) in my php extension. (All extension files is attached - test.zip) The idea in php:
<?php
$arr = [1 => [], 2 => [4, 5]];
$key = 5;
$n = 7;
var_dump($arr);
$arr[$key] = $n; // <=> test_test1($arr, $key, $n); THIS operation
var_dump($arr);
I do the following in extention C code:
PHP_FUNCTION(test_test1)
{
zval *arr;
zend_long key, n;
ZEND_PARSE_PARAMETERS_START(3, 3)
Z_PARAM_ZVAL(arr)
Z_PARAM_LONG(key)
Z_PARAM_LONG(n)
ZEND_PARSE_PARAMETERS_END();
zval *subarr = zend_hash_index_find(Z_ARR_P(arr), key);
if (subarr == NULL)
{
zval temp;
subarr = &temp;
array_init(subarr);
zend_hash_index_add(Z_ARR_P(arr), key, subarr);
}
zval zv;
ZVAL_LONG(&zv, n);
zend_hash_next_index_insert(Z_ARR_P(subarr), &zv);
}
After compilation C code gives: php: /home/.../Downloads/php-src-php-7.4.10/Zend/zend_hash.c:965: _zend_hash_index_add_or_update_i: Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed. If i don't pass arr variable as parameter and create and modify arr in test_test1 function - zend_hash_next_index_insert don't give mistake!!(?) Tell, please, what causes this mistake in my case.
Your function gets constant (immutable) array, that has to be separated.
PHP_FUNCTION(test_test1)
{
zval *arr;
zend_long key, n;
ZEND_PARSE_PARAMETERS_START(3, 3)
Z_PARAM_ZVAL(arr)
Z_PARAM_LONG(key)
Z_PARAM_LONG(n)
ZEND_PARSE_PARAMETERS_END();
zval *subarr = zend_hash_index_find(Z_ARR_P(arr), key);
if (subarr == NULL)
{
zval temp;
array_init(&temp);
SEPARATE_ARRAY(arr);
subarr = zend_hash_index_add(Z_ARR_P(arr), key, &temp);
}
zval zv;
ZVAL_LONG(&zv, n);
SEPARATE_ARRAY(subarr);
zend_hash_next_index_insert(Z_ARR_P(subarr), &zv);
}
Thank you for your reply. I followed your recomendation, but i got another mistake: "Segmentation fault (core dumped)". As i understand it occures on the second SEPARATE_ARRAY macros. What should i do next?
probably, "subarr" may be not an array. You should check if (Z_TYPE_P(subarr) == IS_ARRAY) and handle non-array case.
I added IS_ARRAY checking, but nothing has changed. "Segmentation fault (core dumped)" mistake persists. "subarr" is always an array. I understand that our dialog is out of origin topic, but my situation is pressing. Help me please. I attach all extention files - test.zip