Thanks Tassilo! I did not know about savepv, very convenient, like strdup. Just curious, is the the SV memory being re-used, or is it not going out of scope? I didn't think it would be static.
On Mon, 2004-04-19 at 12:54, Tassilo von Parseval wrote: > On Mon, Apr 19, 2004 at 12:08:03PM -0500 Scott T. Hildreth wrote: > > > I have a xsub that has a pointer to a c-structure, and a sv as the > > parameters, > > > > IV > > set_fld_name(fld, name) > > > > FLD * fld > > SV * name > > PREINIT: > > STRLEN len; > > CODE: > > if (name == (SV *)NULL) > > RETVAL = 0; > > else { > > fld->name = SvPV(name, len); > > RETVAL = 1; > > } > > OUTPUT: > > RETVAL > > > > > > ..which changes the name of a 'fld->name'. Which works fine if I only > > change one name. If the sub is called more than once the 'fld->name' > > pointers all point to the same string. The name is a my variable passed > > in via a method, so I thought there would be an SV created, but the fld > > names changed all point to the same memory, and have the same string. I > > used Devel::Peek to confirm that the address is same. Here is the > > method, > > > > sub set_name { > > my ($self, $fldnm) = @_; > > my $rc; > > my $newself = {}; > > > > $fldnm = lc $fldnm; #== Fmt is case insensitive. > > $rc = fmt_set_fld_name($self->{_ptr}, $fldnm); > > > > . > > . > > . > > return $newself > > } > > > > .. so the address of $fldnm is always the same (static). Therefore the > > fld->names that are sent in all point to the same address. How do I get > > a new SV so that the memory area is different. > > By making a copy: > > fld->name = savepv( SvPV(name, len) ); > > If you don't do that, you'll sooner or later get corrupted memory. You > pass a mortal scalar to the XSUB and use the pointer to its PV slot > elsewhere. Perl doesn't know that and once it frees this scalar, the > pointer is garbage as well. > > Another thing you could probably do is not making a copy but > incrementing the scalar's refcount: > > fld->name = SvPV(name, len); > SvREFCNT_inc(name); > > and decrementing it accordingly once you no longer need to the pointer. > > Tassilo