Do I have to free a HV* created with newHV?
Asked Answered
D

2

8

If I write some XS code with a hash that I never expect to return to perl, do I have to free it? If so, how?

The closest I've come up with is hv_undef, but that is only clearing out the contents of the hash, not the hash itself, from what I understand.

HV* hash = newHV();
...
use the hash
...
hv_undef(hash);
Dennisedennison answered 24/12, 2012 at 19:46 Comment(0)
B
10

newHV (like newSV, newAV, etc.) sets the reference count of the newly created value to 1. To free it, you just need to decrement it to 0. There's no special function for that for HVs, so just use SvREFCNT_dec:

HV* hash = newHV();
/*
 * use the hash
 */
SvREFCNT_dec((SV *) hash);
Barrow answered 24/12, 2012 at 21:46 Comment(1)
Super. I guess the part of HV as a subclass of SV was not working in my head. This works great.Dennisedennison
N
7

newHV returns an HV with a reference count (refcnt) of one, signifying your code's hold on that HV. When you're done with that HV, you must release your hold on it by decrementing its refcnt. There are three common ways of doing this.

  1. Done with it here and now.

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

    AV and HV are "subclasses" of SV.

  2. Done with it after the caller has a chance to reference it. (Doesn't really apply to hashes.)

    return sv_2mortal(sv);
    
  3. Transfer "ownership".

    rv = newRV_noinc((SV*)hv);
    

    That's short for

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

    Note that you must similarly release your hold on the rv when you're done with it, so you'll often see the following:

    return sv_2mortal(newRV_noinc((SV*)hv));
    
Nephritic answered 25/12, 2012 at 4:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.