[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