Нужно ли освобождать HV*, созданное с помощью newHV?

Если я напишу некоторый код XS с хешем, который я никогда не собираюсь возвращать в Perl, должен ли я его освободить? Если так, то как?

Самым близким, что я придумал, является hv_undef, но это только очистка содержимого хэша, а не самого хэша, от того, что я понимаю.

HV* hash = newHV();
...
use the hash
...
hv_undef(hash);

2 ответа

Решение

newHV (лайк newSV, newAVи т. д.) устанавливает счетчик ссылок вновь созданного значения равным 1. Чтобы освободить его, вам просто нужно уменьшить его до 0. Для этого нет специальной функции, так что просто используйте SvREFCNT_dec:

HV* hash = newHV();
/*
 * use the hash
 */
SvREFCNT_dec((SV *) hash);

newHV возвращает HV со счетчиком ссылок (refcnt), равным единице, что означает, что ваш код удерживает HV, Когда вы закончите с этим HV, вы должны освободить его, уменьшив его refcnt. Есть три распространенных способа сделать это.

  1. Сделано с этим здесь и сейчас.

    SvREFCNT_dec((SV*)hv);
    // hv is no longer safe to use here.
    

    AV а также HV являются "подклассами" SV,

  2. Сделано с этим после того, как у вызывающей стороны есть шанс сослаться на это. (На самом деле не относится к хешам.)

    return sv_2mortal(sv);
    
  3. Передача "собственности".

    rv = newRV_noinc((SV*)hv);
    

    Это коротко для

    rv = newRV((SV*)hv);
    SvREFCNT_dec((SV*)hv);
    

    Обратите внимание, что вы должны аналогичным образом отпустить rv когда вы закончите с этим, вы будете часто видеть следующее:

    return sv_2mortal(newRV_noinc((SV*)hv));
    
Другие вопросы по тегам