Topic: [risolto][C-API]Memory leak  (Letto 810 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Bakuriu

  • python sapiens sapiens
  • ******
  • Post: 2.267
  • Punti reputazione: 2
  • Katon, Goukakyuu no jutsu!
    • Mostra profilo
    • Jack's Blackboard - Il mio blog
[risolto][C-API]Memory leak
« il: Settembre 16, 2012, 21:50 »
Sono di nuovo alle prese con i miei bei polinomi modulo x^r-1.
Per implementarli questa volta sto usando la libreria flint, che devo dire, mi sembra molto semplice, flessibile e potente.

Ho però scoperto di avere un memory leak da qualche parte, ma non riesco a capire esattamente dove.
Ho trovato che anche solo fare qualcosa come:
[codice]for _ in xrange(10000):
    a = ModPolynomial(100, 100)[/codice]
consuma memoria, e quindi il memory leak si dovrebbe trovare nell'"init" di quella classe.

Il codice è questo:

[codice=c]
static int
ModPoly_init(PyObject *self, PyObject *args, PyObject *kwds) {
    Py_ssize_t r;
    PyObject *n;
    ModPolyObject *Tself;
    
    if (!PyArg_ParseTuple(args, "nO", &r, &n)) {
        return -1;
    } else if(!PyInt_Check(n) && !PyLong_Check(n)) {
        PyErr_SetString(PyExc_TypeError, "The n modulus must be an integer.");
        return -1;
    }
    
    Tself = (ModPolyObject *)self;
    
    fmpz_init(Tself->n_mod);    /* alloca memoria per "n_mod" */
    
    if (Int_ToFmpz(n, Tself->n_mod) == -1) {  /* converte da python int a fmpz */
        
        fmpz_clear(Tself->n_mod);   /* in caso di errore dealloca */
        return -1;
    }
    
    fmpz_init_set_ui(Tself->r_mod, r);   /* alloca r_mod e lo imposta a "r" */
  
    fmpz_mod_poly_init2(Tself->poly, Tself->n_mod, 2);   /* alloca "poly" per 2 coefficienti */
  
    fmpz_mod_poly_set_coeff_ui(Tself->poly, 1, 1);          /* imposta il valore del polinomio a "x" */
    
    Tself->initialized = POLY_INITIALIZED;
    return 0;
}

/* il distruttore */
static void
modpoly_destructor(ModPolyObject *self) {
    /* Se il polinomio era stato inizializzato completamente dealloca i vari campi
    Ho verificato che viene chiamato e che viene eseguito il codice nell'if */
    if (self->initialized == POLY_INITIALIZED) {
        fmpz_mod_poly_clear(self->poly);
        fmpz_clear(self->r_mod);
        fmpz_clear(self->n_mod);
    }
}

/* Conversione da python int a fmpz */
int
Int_ToFmpz(PyObject *pyint, fmpz_t res) {
    PyObject *s_tmp;
    char *tmp_str;
    
    s_tmp = PyObject_Str(pyint);
    if (s_tmp == NULL) {
        return -1;
    }
    tmp_str = PyString_AsString(s_tmp);
    /* non dealloco tmp_str perchè è gestita da "s_tmp" */
    
    if (tmp_str == NULL) {
        Py_DECREF(s_tmp);
        return -1;
    } else if (fmpz_set_str(res, tmp_str, 10) != 0) {
        Py_DECREF(s_tmp);
        PyErr_SetString(PyExc_TypeError,
                        "Could not convert object to a valid integer "
                        "representation.");
        return -1;
    }
    Py_DECREF(s_tmp);
    return 0;
}

[/codice]

Io non riesco a capire dove c'è questo memory leak. Mi pare che tutte le cose che alloco vengono deallocate, o comunque vengono deallocate dal distruttore.

edit2:
Ho un po' tappezzato di printf il codice, per vedere quello che succede, ma l'output mi conferma che tutto ciò che alloco viene deallocato.

edit(ot):
finalmente ho capito come si cambia linguaggio da evidenziare. Bisogna scrivere "codice=linguaggio" -.-
« Ultima modifica: Settembre 17, 2012, 08:46 da Bakuriu »

Offline Giornale di Sistema

  • python sapiens sapiens
  • ******
  • Post: 3.124
  • Punti reputazione: 4
    • Mostra profilo
    • Distillato di Python
Re: [C-API]Memory leak
« Risposta #1 il: Settembre 16, 2012, 21:59 »
edit(ot):
finalmente ho capito come si cambia linguaggio da evidenziare. Bisogna scrivere "codice=linguaggio" -.-

Oh, ecco... grazie!  :ok:

Offline Bakuriu

  • python sapiens sapiens
  • ******
  • Post: 2.267
  • Punti reputazione: 2
  • Katon, Goukakyuu no jutsu!
    • Mostra profilo
    • Jack's Blackboard - Il mio blog
Re: [C-API]Memory leak
« Risposta #2 il: Settembre 17, 2012, 08:46 »
D'oh! Ero così preso dal controllare di gestire i campi dentro all'oggetto, che mi sono dimenticato di controllare se l'oggetto in se veniva deallocato.
Nel distruttore mancava una chiamata a self->ob_type->tp_free((PyObject *)self).