diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2003-04-21 14:19:50 +0100 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2003-04-23 19:11:01 +0000 |
commit | cccede5366275457276b68bb148b7872098aaf29 (patch) | |
tree | dfb369913110eaa12ba8081f848043cf051b63b5 | |
parent | 1de32f2a8367111f29377c6ed81b538f36717dd9 (diff) | |
download | perl-cccede5366275457276b68bb148b7872098aaf29.tar.gz |
A new fatal error :
Subject: [PATCH] Perl_croak("Use of freed value in iteration")
Message-ID: <20030421121950.GB18189@fdgroup.com>
Message-ID: <20030421125433.GC18189@fdgroup.com>
p4raw-id: //depot/perl@19316
-rw-r--r-- | pod/perldiag.pod | 12 | ||||
-rw-r--r-- | pp_hot.c | 6 | ||||
-rwxr-xr-x | t/cmd/for.t | 7 |
3 files changed, 24 insertions, 1 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 92c4d8a40c..3baec3a64c 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -4225,6 +4225,18 @@ defined B<awk> feature. Use an explicit printf() or sprintf() instead. generally because there's a better way to do it, and also because the old way has bad side effects. +=item Use of freed value in iteration (perhaps you modified the iterated array within the loop?) + +(F) This is typically caused by code like the following: + + @a = (3,4); + @a = () for (1,2,@a); + +You are not supposed to modify arrays while they are being iterated over. +For speed and efficiency reasons, Perl internally does not do full +reference-counting of iterated items, hence deleting such an item in the +middle of an iteration causes Perl to see a freed value. + =item Use of reference "%s" as array index (W misc) You tried to use a reference as an array index; this probably @@ -1859,6 +1859,12 @@ PP(pp_iter) else { sv = AvARRAY(av)[++cx->blk_loop.iterix]; } + if (sv && SvREFCNT(sv) == 0) { + *itersvp = Nullsv; + Perl_croak(aTHX_ + "Use of freed value in iteration (perhaps you modified the iterated array within the loop?)"); + } + if (sv) SvTEMP_off(sv); else diff --git a/t/cmd/for.t b/t/cmd/for.t index 3275c71d2a..3a4bc9b0da 100755 --- a/t/cmd/for.t +++ b/t/cmd/for.t @@ -1,6 +1,6 @@ #!./perl -print "1..12\n"; +print "1..13\n"; for ($i = 0; $i <= 10; $i++) { $x[$i] = $i; @@ -71,3 +71,8 @@ for ("-3" .. "0") { $loop_count++; } print $loop_count == 4 ? "ok" : "not ok", " 12\n"; + +# modifying arrays in loops is a no-no +@a = (3,4); +eval { @a = () for (1,2,@a) }; +print $@ =~ /Use of freed value in iteration/ ? "ok" : "not ok", " 13\n"; |