diff options
author | Karl Williamson <khw@cpan.org> | 2015-03-28 20:54:49 -0600 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2015-03-28 20:58:54 -0600 |
commit | 38f18a308b948c6eaf187519a16d060e1ec7cc20 (patch) | |
tree | aea52bc4f6f7535f3d00cc811bc8953603d8b222 /pod/perlhacktips.pod | |
parent | 008e8e82d7383361068156624879df7566121878 (diff) | |
download | perl-38f18a308b948c6eaf187519a16d060e1ec7cc20.tar.gz |
perlhacktips: Add caution about clib ptr returns to static memory
Diffstat (limited to 'pod/perlhacktips.pod')
-rw-r--r-- | pod/perlhacktips.pod | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/pod/perlhacktips.pod b/pod/perlhacktips.pod index 7b345167b8..834c8c8766 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 |