summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@engin.umich.edu>1997-05-15 23:30:26 +1200
committerTim Bunce <Tim.Bunce@ig.co.uk>1997-06-11 12:00:00 +1200
commit5117ca915f2c72e17e52c313797ad394bd76c418 (patch)
treee84e21fff4b9114c15db093f0b5833573839083a
parentc8756f30ff24381844a7b05f062074a87dc23910 (diff)
downloadperl-5117ca915f2c72e17e52c313797ad394bd76c418.tar.gz
No DESTROY on untie. Tie memory leak fixed.
Subject: Re: Bug w/ DB_File: no flush on untie On Sat, 17 May 1997 16:06:26 BST, Paul Marquess wrote: > >Good bug report Jay. Thanks. I'll say! >Turns out this isn't a DB_File problem but a tied hash/array problem. >Running this script: > > package fred ; > sub TIEHASH { return bless [] } > sub TIEARRAY { return bless [] } > sub FETCH { print "FETCH\n"} > sub STORE { print "STORE\n"} > sub CLEAR { print "CLEAR\n"} > sub DESTROY { print "DESTROY\n" } > > package main ; > > tie %x, 'fred' ; > %x = (1,2,3,4) ; > $x{2} = 3 ; > untie %x ; > print "untied\n" ; > >I got > > CLEAR > STORE > STORE > STORE > untied > DESTROY > >The tied object isn't getting destroyed until global destruction at the >end. That is a bug. I'd guess that something in the logic to do array >assignments is holding on to the tied object and not letting go. > >The story is the same for tied arrays. > >Who said they were going to take on the tied stuff post 5.004? That's partly on my plate. This bug (a memory leak, actually) has been around since the beginning of time, and I'm thoroughly stupefied that it hasn't been noticed before. Here's a fix. People who have made noises before about ties being memory hogs should give this patch a try. p5p-msgid: 199705172156.RAA20561@aatma.engin.umich.edu Signed-off-by: Jay Rogers <jay@rgrs.com> Signed-off-by: Paul Marquess <pmarquess@bfsec.bt.co.uk>
-rw-r--r--pp_hot.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/pp_hot.c b/pp_hot.c
index e48a010554..2f044b9a1d 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -625,13 +625,17 @@ PP(pp_aassign)
av_extend(ary, lastrelem - relem);
i = 0;
while (relem <= lastrelem) { /* gobble up all the rest */
+ SV **didstore;
sv = NEWSV(28,0);
assert(*relem);
sv_setsv(sv,*relem);
*(relem++) = sv;
- (void)av_store(ary,i++,sv);
- if (magic)
+ didstore = av_store(ary,i++,sv);
+ if (magic) {
mg_set(sv);
+ if (!didstore)
+ SvREFCNT_dec(sv);
+ }
TAINT_NOT;
}
break;
@@ -644,6 +648,7 @@ PP(pp_aassign)
while (relem < lastrelem) { /* gobble up all the rest */
STRLEN len;
+ HE *didstore;
if (*relem)
sv = *(relem++);
else
@@ -652,9 +657,12 @@ PP(pp_aassign)
if (*relem)
sv_setsv(tmpstr,*relem); /* value */
*(relem++) = tmpstr;
- (void)hv_store_ent(hash,sv,tmpstr,0);
- if (magic)
+ didstore = hv_store_ent(hash,sv,tmpstr,0);
+ if (magic) {
mg_set(tmpstr);
+ if (!didstore)
+ SvREFCNT_dec(tmpstr);
+ }
TAINT_NOT;
}
if (relem == lastrelem)