I had the following code in an XS module. It is attempting to cycle through all of the entries in the scratchpad associated with a sub, and for each entry having a valid name, where the name also is found in another hash, I want to do something.

for (i = 0; i <= av_len(padn); ++i) { HE *hent; SV **nameptr = av_fetch(padn, i, 0); if (nameptr != NULL && SvPOKp(*nameptr) && (hent = hv_fetch_ent(hvn, *nameptr, 0, 0)) != NULL) { /* do something interesting with the value from hent */ } }

This worked, most of the time. However, for two of the names I was interested in, *nameptr was valid but the hv_fetch_ent failed, even though the name was in the hash indicated by hvn (which is HV *).

I then changed it to something like this:

for (i = 0; i <= av_len(padn); ++i) { HE *hent; SV **nameptr = av_fetch(padn, i, 0); if (nameptr != NULL && SvPOKp(*nameptr)) { SV **field; U32 len; const char *name = SvPV(*nameptr, len); if ((field = hv_fetch(hvn, name, len, 0)) != NULL) { /* do something interesting with *field */ } } }

but that failed in the same way.

I did some research (i.e., lots of printfs) and discovered that in these two cases _only_, the length associated with *nameptr was too large. One of the values was six characters long, the other was 5 (names "@stack" and "@trim" respectively), but the lengths were 235 and 236, respectively. I found it interesting but not enlightening that the wrong values were both 241 minus the correct value.

The code I have now works, but I am less than happy with it:

for (i = 0; i <= av_len(padn); ++i) { SV **nameptr = av_fetch(padn, i, 0); if (nameptr != NULL && SvPOKp(*nameptr)) { SV **field; const char *name = SvPV_nolen(*nameptr); if ((field = hv_fetch(hvn, name, strlen(name), 0)) != NULL) { /* do something interesting with *field */ } } }

In other words, the length associated with the SV* is wrong, but using good ol' C "strlen" works. Huh?

I know this borders on (if it doesn't cross into) forbidden magic, so maybe I should just accept that there are things I wasn't Meant To Know, but I am interested to hear if anyone has any clues about this Why didn't the length match up? Why did only some of them not match up (I didn't mention it, but one of the things I did was print out the name and name lengths of everything where *nameptr was valid). Why did the same names work properly some places?

This is perl, v5.8.6 built for darwin-thread-multi-2level (with 3 registered patches, see perl -V for more detail)

Kevin, perplexed


In reply to Invalid SV name length in pad? by 7th Kevin

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.