[Moscow.pm] Вопрос про возвращаемые значения из Perl XS
Mons Anderson
mons на cpan.org
Пт Июл 9 08:54:31 PDT 2010
On Friday 09 July 2010 19:12:28 aznaourian nikita wrote:
> Есть XS процедура, которая возвращает ссылку на массив SV*.
>
> В процедуре создается новый массив
>
> AV* array = (AV*)sv_2mortal((SV*)newAV());
>
> AV* array2 = newAV();
>
> av_push(newArray, newSVpv("value2", 0));
> av_push(newArray, (SV*)newArray2);
>
> return newRV((SV*)newArray);
>
> При этом в перле выводится следующее:
> [
> 'value',
> undef
> ];
>
По моему вы делаете что-то очень страшное
Если вы хотите вернуть ссылку на массив, это
SV* arrayref = newRV_noinc( newAV() );
можно также заморталить:
SV* mortal_arrayref = sv_2mortal(newRV_noinc( newAV() ));
ваш вариант по видимому
AV* array = newAV();
AV* array2 = newAV();
av_push(array, newSVpv("value2", 0));
av_push(array, newRV_noinc( array2 ));
return sv_2mortal(newRV_noinc(array));
> cобсвтенно вопрос - почему? Как работает XS сборщик мусора? Понятно, что
> REFCNT для newArray2 = 1, Но он также равен 1 и для newSVpv(...) В чем
> разница между этими двумя указателями?
newAV возвращает AV с установленным refcnt = 1;
если мы делает newRV(newAV()), то получает refcnt на AV'шке = 2 и refcnt на
RV'шке = 1
если мы делает newRV_noinc(newAV()), то получает refcnt на AV'шке = 1 и
refcnt на RV'шке = 1. т.е. следить нужно только за RV'шкой.
>
> Понятно, что можно это исправить , если второй массив тоже сделать с
> mortal. Но не понятно, почему, так происходит.
>
морталить имеет смысл только общую структуру, которая содержит в себе все
элементы.
в противном случае получите Attempt to free unreferenced...
т.е. если вы создаете массив и его морталите, то элементы, который вы в него
складываете морталить не нужно. при вызове FREETMPS (уничтожение морталов) у
вас уничтожится морталеный массив, и т.к. кол-во ссылок на элементы этого
массива уменьшится до 0 они тоже уничтожатся.
--
Mons Anderson aka Vladimir Perepelitsa
<mons на cpan.org> / #99779956 / quanth на irc.freenode.net
Подробная информация о списке рассылки Moscow-pm