-----BEGIN PGP SIGNED MESSAGE-----

Moin,

I have seen some alarming memory growth on an application of mine, and have 
the hunch that Math::BigInt::GMP is leaking memory. The included test script 
outputs:

[snip 196 lines]
new 0x816d5f0 :
new 0x816d5fc :
  subtract leaked 197 things
new 0x832ae0c :
  divide leaked 1 things
  add leaked 0 things
  mod leaked 0 things
  pow leaked 0 things
  xor leaked 0 things
  ior leaked 0 things
  and leaked 0 things
  -= leaked 0 things
  += leaked 0 things
  %= leaked 0 things
  /= leaked 0 things

Here is the code for my sub():

#define NEW_GMP_MPZ_T      RETVAL = malloc (sizeof(mpz_t));
#define NEW_GMP_MPZ_T_INIT RETVAL = malloc (sizeof(mpz_t)); mpz_init(*RETVAL);
#define GMP_GET_ARG_0      if (sv_derived_from(x, "Math::BigInt::GMP")) {\
                           IV tmp = SvIV((SV*)SvRV(x));\
                           TEMP = (mpz_t*) tmp;\
                  } else { croak("x is not of type Math::BigInt::GMP"); }
#define GMP_GET_ARG_1      if (sv_derived_from(y, "Math::BigInt::GMP")) {\
                           IV tmp = SvIV((SV*)SvRV(y));\
                           TEMP_1 = (mpz_t*) tmp;\
                  } else { croak("y is not of type Math::BigInt::GMP"); }
#define GMP_GET_ARGS_0_1   GMP_GET_ARG_0; GMP_GET_ARG_1;

##############################################################################
# _sub() - $x - $y
# $x is always larger than $y! So overflow/underflow can not happen here.
# Formerly this code was:
# # if ($_[3])
#    {
#    $_[2] = Math::BigInt::GMP::sub_two($_[1],$_[2]); return $_[2];
#    }
#  Math::BigInt::GMP::_sub_in_place($_[1],$_[2]);
#  }

void
_sub(Class,x,y, ...)
        SV*     x
        SV*     y
  PREINIT:
        mpz_t* TEMP;
        mpz_t* TEMP_1;
        mpz_t* TEMP_2;
  PPCODE:
    GMP_GET_ARGS_0_1;   /* (TEMP, TEMP_1) = (x,y)  */
    if ( items == 4 && SvTRUE(ST(3)) )
      {
      /* return new(y - x) */
      /* need to create TEMP_2 or it will ssegfault */
      TEMP_2 = malloc (sizeof(mpz_t)); mpz_init(*TEMP_2);

      mpz_sub(*TEMP_2, *TEMP, *TEMP_1);

      PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)TEMP_2));
      /*PUSHs(sv_setref_pv(y, "Math::BigInt::GMP", (void*)TEMP_2)); */
      }
    else
      {
      /* x -= y */
      mpz_sub(*TEMP, *TEMP, *TEMP_1);
      PUSHs( x );
      }

It doesn't matter whether I use the newmortal() or the line below it, subtract 
still leaks (although it changes from 199 to 197 things when using the 
sv_newmortal() line). I am really lost here as whether this code leaks 
scalars, and why it leaks so many of them!

The full code of Math::BigInt::GMP is on CPAN.

Thanx for any insight,

Tels

#!/usr/bin/perl -w

use strict;
use lib 'lib';
use lib 'blib/arch';
use Math::BigInt lib => 'GMP';

my $x = Math::BigInt->new(44);
my $y = Math::BigInt->new(21);

use Devel::Leak;

for my $do (
  [ sub { my $z = $x - $y; 1; }, 'subtract' ],
  [ sub { my $z = $x / $y; 1; }, 'divide' ],
  [ sub { my $z = $x + $y; 1; }, 'add' ],
  [ sub { my $z = $x % $y; 1; }, 'mod' ],
  [ sub { my $z = $x ** $y; 1; }, 'pow' ],
  [ sub { my $z = $x ^ $y; 1; }, 'xor' ],
  [ sub { my $z = $x | $y; 1; }, 'ior' ],
  [ sub { my $z = $x & $y; 1; }, 'and' ],
  [ sub { my $z = $x; $z -= $y; 1; }, '-=' ],
  [ sub { my $z = $x; $z += $y; 1; }, '+=' ],
  [ sub { my $z = $x; $z %= $y; 1; }, '%=' ],
  [ sub { my $z = $x; $z /= $y; 1; }, '/=' ],
 )
  {
  my $handle;
  my $count = Devel::Leak::NoteSV($handle);
  &{$do->[0]};
  print "  $do->[1] leaked ",
  Devel::Leak::CheckSV($handle) - $count, " things\n";
  }

- -- 
 Signed on Sun Nov 28 14:24:26 2004 with key 0x93B84C15.
 Visit my photo gallery at http://bloodgate.com/photos/
 PGP key on http://bloodgate.com/tels.asc or per email.

 "The rovers Spirit and Opportunity were proposed, authorized, announced,
 designed, launched and successfully landed upon Mars within the timeframe
 of Duke Nukem Forever's development." - Unknown

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iQEVAwUBQanRlHcLPEOTuEwVAQHFFAf+PTMeuy5qaR65V2nTevHHk2YkgK0ZrITm
iiUNmRqyzL3uLDtNfALGZtrBg7vfHE4Z3yGHcjKmivXhOCFnOg5CbSw3R+bVbgHy
97tQ1M7VKpcPQadfQPxh/SlDeIvDvkLWEV/PVp556Tw0sTidBvQiF7hA5cNsXZXU
LlP6uKj5nfi+n+sP2O6JT80GHbv+D8dMr8cVv59mu48z/+rLeb8yTgRd+oK4gJVd
SONH4VZ07go/FTU92upoRJGbKD4q/0SzunHwQBVQtDRKLQi9CpN0wBOwgByZjMvC
CE+oZK/hKN3ot8/8KQpSq1Y07xKuIWZdwE+HPlhRfrtAmsYekOf9QQ==
=cRyI
-----END PGP SIGNATURE-----

Reply via email to