1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

Fix bignum memory leak.

The `mpz_t' associated with a bignum would never be freed, so an
expression like `(while #t (expt 2 5000))' would quickly lead to memory
exhaustion.

* libguile/numbers.c (finalize_bignum): New function.
  (make_bignum): Register it as a finalizer for P.
This commit is contained in:
Ludovic Courtès 2010-09-27 11:20:14 +02:00
parent d017fcdfcb
commit 864e7d424e

View file

@ -60,6 +60,7 @@
#include "libguile/root.h"
#include "libguile/smob.h"
#include "libguile/strings.h"
#include "libguile/bdw-gc.h"
#include "libguile/validate.h"
#include "libguile/numbers.h"
@ -152,20 +153,37 @@ scm_from_complex_double (complex double z)
static mpz_t z_negative_one;
/* Clear the `mpz_t' embedded in bignum PTR. */
static void
finalize_bignum (GC_PTR ptr, GC_PTR data)
{
SCM bignum;
bignum = PTR2SCM (ptr);
mpz_clear (SCM_I_BIG_MPZ (bignum));
}
/* Return a new uninitialized bignum. */
static inline SCM
make_bignum (void)
{
scm_t_bits *p;
GC_finalization_proc prev_finalizer;
GC_PTR prev_finalizer_data;
/* Allocate one word for the type tag and enough room for an `mpz_t'. */
p = scm_gc_malloc_pointerless (sizeof (scm_t_bits) + sizeof (mpz_t),
"bignum");
p[0] = scm_tc16_big;
GC_REGISTER_FINALIZER_NO_ORDER (p, finalize_bignum, NULL,
&prev_finalizer,
&prev_finalizer_data);
return SCM_PACK (p);
}
SCM
scm_i_mkbig ()
{