In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/38f18a308b948c6eaf187519a16d060e1ec7cc20?hp=008e8e82d7383361068156624879df7566121878>
- Log ----------------------------------------------------------------- commit 38f18a308b948c6eaf187519a16d060e1ec7cc20 Author: Karl Williamson <[email protected]> Date: Sat Mar 28 20:54:49 2015 -0600 perlhacktips: Add caution about clib ptr returns to static memory ----------------------------------------------------------------------- Summary of changes: pod/perlhacktips.pod | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pod/perlhacktips.pod b/pod/perlhacktips.pod index 7b34516..834c8c8 100644 --- a/pod/perlhacktips.pod +++ b/pod/perlhacktips.pod @@ -574,6 +574,39 @@ temporarily try the following: But in any case, try to keep the features and operating systems separate. +=item * + +Assuming the contents of static memory pointed to by the return values +of Perl wrappers for C library functions doesn't change. Many C library +functions return pointers to static storage that can be overwritten by +subsequent calls to the same or related functions. Perl has +light-weight wrappers for some of these functions, and which don't make +copies of the static memory. A good example is the interface to the +environment variables that are in effect for the program. Perl has +C<PerlEnv_getenv> to get values from the environment. But the return is +a pointer to static memory in the C library. If you are using the value +to immediately test for something, that's fine, but if you save the +value and expect it to be unchanged by later processing, you would be +wrong, but perhaps you wouldn't know it because different C library +implementations behave differently, and the one on the platform you're +testing on might work for your situation. But on some platforms, a +subsequent call to C<PerlEnv_getenv> or related function WILL overwrite +the memory that your first call points to. This has led to some +hard-to-debug problems. Do a L<perlapi/savepv> to make a copy, thus +avoiding these problems. You will have to free the copy when you're +done to avoid memory leaks. If you don't have control over when it gets +freed, you'll need to make the copy in a mortal scalar, like so: + + if ((s = PerlEnv_getenv("foo") == NULL) { + ... /* handle NULL case */ + } + else { + s = SvPVX(sv_2mortal(newSVpv(s, 0))); + } + +The above example works only if C<"s"> is C<NUL>-terminated; otherwise +you have to pass its length to C<newSVpv>. + =back =head2 Problematic System Interfaces -- Perl5 Master Repository
