[A complimentary Cc of this posting was sent to
cyl
I think you mean newRV_noinc(). With this change no memory increased.
But I am wondering what the lifetime of the array reference is. Will
there be any risk on data corruption when accessing the reference?
There is no notion of "risk" in programming. There is correct code,
and incorrect code ;-). The code above has correct refcounts (here rv
is the return value of newRV_noinc() call):
av(short-time) av(long-time) rv(short-time) rv(long-time)
1 1 after newAV()
1 1 1 1 after newRV_noinc()
1 1 1 0 after sv_2mortal()
SVs returned from XSUBS should have long-time refcount 0 (unless
stored in long-time C pointers; then the refcount should be
incremented correspondingly). av is stored in rv only, so must
have long-time refcount 1. Thus your code is correct.
-------------------------------------------------------
If you had
static AV* stored_array;
....
stored_array = av;
ST(0) = sv_2mortal(newRV((SV*)av));
then the code would be also correct:
av(short-time) av(long-time) rv(short-time) rv(long-time)
1 1 after newAV()
2 2 1 1 after newRV()
2 2 1 0 after sv_2mortal()
now av is referenced from rv and stored_array, so must have long-time
refcount 2 (and you must change refcount manually when stored_array
value is changing).
-------------------------------------------------------
If you had
static SV* stored_ref;
....
SV *rv = newRV_noinc(av)
stored_ref = rv;
ST(0) = rv;
The refcounts would also be correct:
av(short-time) av(long-time) rv(short-time) rv(long-time)
1 1 after newAV()
1 1 1 1 after newRV_noinc()
Now av is stored only in rv, and rv is stored only in stored_ref. So
both long-time refcounts should be 1 on return from XSUB. And they are!
There is no need to sv_2mortal(), since its only purpose is that
short-time refcount of 0 is not possible. So if you need long-time
refcount of 0, you must arrange that REFCNT is decremented at some
later time.
Hope this helps,
Ilya
P.S. There are thousands of different ways to achieve the required
long-time refcounts, by doing arbitrary combinations of
SvREFCNT_inc/dec, different types of newRV, mortalization.
I did not try to achieve a combination which reflects best the
intenet of the programs. All I did was to use fewest number of
calls to reach this target. For example, in stored_array
example, it might be clearer to use newRV_noinc() followed by
SvREFCNT_inc().
P.P.S. Completely untested, and write-only. ;-)