On Fri, Oct 31, 2003 at 12:39:14PM +1100 Sisyphus wrote: > Steve Hay wrote: > > > > >So I tried rewriting my original example like this: > > > >SV * > >hello() > > PREINIT: > > char *chartext; > > SV *svtext; > > > > CODE: > > Newz(0, chartext, 13, char); > > strcpy(chartext, "Hello, world"); > > sv_usepvn(svtext, chartext, 13); > > RETVAL = svtext; > > > > OUTPUT: > > RETVAL > > > >However, I now find that when I call that from Perl ($greeting = > >Foo::hello()) then I get this error: > > > > Modification of a read-only value attempted
I get a segfault, which is what I would expect. You only allocate memory for the string but not for the SV to be returned. > I get the same - except that I don't get any compiler warning at all. > > My 'perlapi' documentation tells me that if I use 'sv_usepvn()', then > chartext needs to have been dynamically allocated with 'malloc()', so I > tried replacing 'Newz()' with 'malloc()'. That also compiles ok, but > when run it crashes and Windows shuts it down without producing any > meaningful error message. > > I find no problem with newSVpv() - irrespective of whether I allocate > chartext with 'Newz()' or 'malloc()'. Beyond that, *I* can't really help. You should always prefer New() (or Newz()) over your system's memory allocator. It is a macro that uses whatever memory-allocating-mechanism perl was compiled with and finds appropriate. Particularly, some systems have a buggy malloc() that perl can work around. In most cases however, these macros() expand to the traditional malloc(). It's no wonder that it works with newSVpv(), because this will allocate and create a new SV. The above code doesn't. One could change it to: SV * hello() PREINIT: char *chartext; SV *svtext; CODE: Newz(0, chartext, 13, char); svtext = newSV(0); strcpy(chartext, "Hello, world"); sv_usepvn(svtext, chartext, strlen(chartext)); RETVAL = svtext; OUTPUT: RETVAL Note that 'chartext' is deliberately not freed here. > Nick or Tassilo (and no doubt others) might be able to throw some light > on it - I couldn't get anywhere with 'use_svpvn()'. (I'm curious about > it, too :-) Maybe you couldn't get anywhere with 'use_svpvn' because it really should be 'sv_usepvn'. ;-) Tassilo -- $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({ pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#; $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval