It has been altogether too long since I wrote XS code. I have some code which goes through an array and splices out a certain value:

void _drop_node(HV* a, SV* activelist) {
    AV* newlist = newAV();
    I32 i = 0;
    while (i <= av_len((AV*)SvRV(activelist))) {
        SV** x = av_fetch((AV*)SvRV(activelist), i, 0);
        if (*x && SvRV(*x) && SvRV(*x) != (SV*)a)
            av_push(newlist, newSVsv(*x));
        i++;
    }
    SvRV_set(activelist, (SV*)newlist);
}

This works, but it's horrible and it leaks like a sieve. I'd like to fix the leak, but ideally I'd prefer to replace it with more sensible code. So I tried this instead:

void _drop_node(HV* a, SV* activelist) {
    SV** src;
    AV* ary = (AV*)SvRV(activelist);
    I32 i = 0;
    i=0;
    while (i <= AvFILLp(ary)) {
        SV** x = AvARRAY(ary) + i;
        if (*x && SvRV(*x) && SvRV(*x) == (SV*)a) break;
        i++;
    }
    src = AvARRAY(ary) + i + 1;
    Move(src,src - 1, AvFILLp(ary) - i + 1, SV*);
    AvFILLp(ary)--;
}

(Last three lines stolen from pp.c:pp_splice.) Unfortunately, this seems to do the right thing to the array but it messes up existing pointers to things that used to be in the array - tests are giving strangely wrong answers.

I don't know what to do at this point. Can anyone help? (The module is Text::KnuthPlass, if anyone's interested, and there's a similarly leaky function called _insert_before that I'd also like to fix up.)

Reply via email to