From 51288bce482d076917c5ce5a3a5b48e7aa6031cb Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 19 Mar 1999 20:30:39 +0000 Subject: [PATCH] Fix a problem with Vladimir's PyInt_Fini code: clear the free list; if a block cannot be freed, add its free items back to the free list, and add its valid ints back to the small_ints array if they are in range. This is necessary to avoid leaking when Python is reinitialized later. --- Objects/intobject.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Objects/intobject.c b/Objects/intobject.c index 0bf1fc54540..7293515e6c3 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -831,11 +831,13 @@ PyInt_Fini() isum = 0; list = block_list; block_list = NULL; + free_list = NULL; while (list != NULL) { - p = &list->objects[0]; bc++; irem = 0; - for (i = 0; i < N_INTOBJECTS; i++, p++) { + for (i = 0, p = &list->objects[0]; + i < N_INTOBJECTS; + i++, p++) { if (PyInt_Check(p) && p->ob_refcnt != 0) irem++; } @@ -843,6 +845,25 @@ PyInt_Fini() if (irem) { list->next = block_list; block_list = list; + for (i = 0, p = &list->objects[0]; + i < N_INTOBJECTS; + i++, p++) { + if (!PyInt_Check(p) || p->ob_refcnt == 0) { + p->ob_type = (struct _typeobject *) + free_list; + free_list = p; + } +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 + else if (-NSMALLNEGINTS <= p->ob_ival && + p->ob_ival < NSMALLPOSINTS && + small_ints[p->ob_ival + + NSMALLNEGINTS] == NULL) { + Py_INCREF(p); + small_ints[p->ob_ival + + NSMALLNEGINTS] = p; + } +#endif + } } else { PyMem_FREE(list); @@ -866,11 +887,12 @@ PyInt_Fini() if (Py_VerboseFlag > 1) { list = block_list; while (list != NULL) { - p = &list->objects[0]; - for (i = 0; i < N_INTOBJECTS; i++, p++) { + for (i = 0, p = &list->objects[0]; + i < N_INTOBJECTS; + i++, p++) { if (PyInt_Check(p) && p->ob_refcnt != 0) fprintf(stderr, - "# \n", + "# \n", p, p->ob_refcnt, p->ob_ival); } list = list->next;