Skip to content

Commit d6c9cff

Browse files
committed
fixed memory leak
1 parent 9678471 commit d6c9cff

File tree

4 files changed

+61
-25
lines changed

4 files changed

+61
-25
lines changed

docs/source/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
=========
33

4+
Version 0.1.3 (2021-05-31)
5+
--------------------------
6+
7+
- Fixed memory leak when iterating over ITRs
8+
49
Version 0.1.2 (2021-05-21)
510
--------------------------
611

src/itr.c

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ static PyObject* stria_itrminer_new(PyTypeObject *type, PyObject *args, PyObject
272272
Py_INCREF(obj->seqobj);
273273

274274
obj->seq = PyUnicode_AsUTF8AndSize(obj->seqobj, &obj->size);
275+
obj->motif = NULL;
276+
obj->matrix = NULL;
275277

276278
return (PyObject *)obj;
277279
}
@@ -280,6 +282,15 @@ void stria_itrminer_dealloc(stria_ITRMiner *self) {
280282
Py_DECREF(self->seqname);
281283
Py_DECREF(self->seqobj);
282284
self->seq = NULL;
285+
286+
if (self->motif) {
287+
free(self->motif);
288+
}
289+
290+
if (self->matrix) {
291+
release_matrix(self->matrix, self->extend_maxlen);
292+
}
293+
283294
Py_TYPE(self)->tp_free((PyObject *)self);
284295
}
285296

@@ -289,6 +300,15 @@ static PyObject* stria_itrminer_repr(stria_ITRMiner *self) {
289300

290301
static PyObject* stria_itrminer_iter(stria_ITRMiner *self) {
291302
self->next_start = 0;
303+
304+
if (!self->motif) {
305+
self->motif = (char *)malloc(self->max_motif + 1);
306+
}
307+
308+
if (!self->matrix) {
309+
self->matrix = initial_matrix(self->extend_maxlen);
310+
}
311+
292312
Py_INCREF(self);
293313
return (PyObject *)self;
294314
}
@@ -320,9 +340,6 @@ static PyObject* stria_itrminer_next(stria_ITRMiner *self) {
320340
double tandem_identity;
321341
double align_rate;
322342

323-
char* motif = (char *)malloc(self->max_motif + 1);
324-
int **matrix = initial_matrix(self->extend_maxlen);
325-
326343
Py_ssize_t boundary;
327344

328345
for (Py_ssize_t i = self->next_start; i < self->size; ++i) {
@@ -361,8 +378,8 @@ static PyObject* stria_itrminer_next(stria_ITRMiner *self) {
361378

362379
if (seed_good) {
363380
//get motif sequence
364-
memcpy(motif, self->seq + seed_start, j);
365-
motif[j] = '\0';
381+
memcpy(self->motif, self->seq + seed_start, j);
382+
self->motif[j] = '\0';
366383

367384
seed_end = seed_start + seed_length - 1;
368385
tandem_match = seed_length;
@@ -378,9 +395,9 @@ static PyObject* stria_itrminer_next(stria_ITRMiner *self) {
378395
extend_maxlen = self->extend_maxlen;
379396
}
380397

381-
extend_end = build_left_matrix(self->seq, motif, j, matrix, extend_start,
398+
extend_end = build_left_matrix(self->seq, self->motif, j, self->matrix, extend_start,
382399
extend_maxlen, self->max_errors);
383-
extend_len = backtrace_matrix(matrix, extend_end, &tandem_match, &substitution,
400+
extend_len = backtrace_matrix(self->matrix, extend_end, &tandem_match, &substitution,
384401
&insertion, &deletion);
385402

386403
if (extend_len > 0) {
@@ -408,9 +425,9 @@ static PyObject* stria_itrminer_next(stria_ITRMiner *self) {
408425
extend_maxlen = self->extend_maxlen;
409426
}
410427

411-
extend_end = build_right_matrix(self->seq, motif, j, matrix, extend_start,
428+
extend_end = build_right_matrix(self->seq, self->motif, j, self->matrix, extend_start,
412429
extend_maxlen, self->max_errors);
413-
extend_len = backtrace_matrix(matrix, extend_end, &tandem_match, &substitution,
430+
extend_len = backtrace_matrix(self->matrix, extend_end, &tandem_match, &substitution,
414431
&insertion, &deletion);
415432

416433
//calcuate the alignment rate of extended sequence
@@ -432,7 +449,7 @@ static PyObject* stria_itrminer_next(stria_ITRMiner *self) {
432449
//create new itr element object
433450
stria_ITR *itr = PyObject_New(stria_ITR, &stria_ITRType);
434451
itr->motif = (char *)malloc(j + 1);
435-
memcpy(itr->motif, motif, j);
452+
memcpy(itr->motif, self->motif, j);
436453
itr->motif[j] = '\0';
437454
itr->mlen = j;
438455
itr->seqid = self->seqname;
@@ -456,8 +473,10 @@ static PyObject* stria_itrminer_next(stria_ITRMiner *self) {
456473
}
457474
}
458475

459-
free(motif);
460-
release_matrix(matrix, self->extend_maxlen);
476+
free(self->motif);
477+
release_matrix(self->matrix, self->extend_maxlen);
478+
self->motif = NULL;
479+
self->matrix = NULL;
461480
return NULL;
462481
}
463482

@@ -490,9 +509,14 @@ static PyObject* stria_itrminer_as_list(stria_ITRMiner *self) {
490509
int tandem_delete;
491510
double tandem_identity;
492511
double align_rate;
493-
494-
char* motif = (char *)malloc(self->max_motif + 1);
495-
int **matrix = initial_matrix(self->extend_maxlen);
512+
513+
if (!self->motif) {
514+
self->motif = (char *)malloc(self->max_motif + 1);
515+
}
516+
517+
if (!self->matrix) {
518+
self->matrix = initial_matrix(self->extend_maxlen);
519+
}
496520

497521
Py_ssize_t boundary;
498522

@@ -532,8 +556,8 @@ static PyObject* stria_itrminer_as_list(stria_ITRMiner *self) {
532556

533557
if (seed_good) {
534558
//get motif sequence
535-
memcpy(motif, self->seq + seed_start, j);
536-
motif[j] = '\0';
559+
memcpy(self->motif, self->seq + seed_start, j);
560+
self->motif[j] = '\0';
537561

538562
seed_end = seed_start + seed_length - 1;
539563
tandem_match = seed_length;
@@ -549,9 +573,9 @@ static PyObject* stria_itrminer_as_list(stria_ITRMiner *self) {
549573
extend_maxlen = self->extend_maxlen;
550574
}
551575

552-
extend_end = build_left_matrix(self->seq, motif, j, matrix, extend_start,
576+
extend_end = build_left_matrix(self->seq, self->motif, j, self->matrix, extend_start,
553577
extend_maxlen, self->max_errors);
554-
extend_len = backtrace_matrix(matrix, extend_end, &tandem_match, &substitution,
578+
extend_len = backtrace_matrix(self->matrix, extend_end, &tandem_match, &substitution,
555579
&insertion, &deletion);
556580

557581
if (extend_len > 0) {
@@ -579,9 +603,9 @@ static PyObject* stria_itrminer_as_list(stria_ITRMiner *self) {
579603
extend_maxlen = self->extend_maxlen;
580604
}
581605

582-
extend_end = build_right_matrix(self->seq, motif, j, matrix, extend_start,
606+
extend_end = build_right_matrix(self->seq, self->motif, j, self->matrix, extend_start,
583607
extend_maxlen, self->max_errors);
584-
extend_len = backtrace_matrix(matrix, extend_end, &tandem_match, &substitution,
608+
extend_len = backtrace_matrix(self->matrix, extend_end, &tandem_match, &substitution,
585609
&insertion, &deletion);
586610

587611
//calcuate the alignment rate of extended sequence
@@ -600,7 +624,7 @@ static PyObject* stria_itrminer_as_list(stria_ITRMiner *self) {
600624
tandem_delete += deletion;
601625
tandem_identity = (tandem_match * 1.0 / tandem_length)*100;
602626

603-
tmp = Py_BuildValue("Onnsiiiiiif", self->seqname, tandem_start, tandem_end, motif, j,
627+
tmp = Py_BuildValue("Onnsiiiiiif", self->seqname, tandem_start, tandem_end, self->motif, j,
604628
tandem_length, tandem_match, tandem_substitute, tandem_insert,
605629
tandem_delete, tandem_identity);
606630
PyList_Append(itrs, tmp);
@@ -616,8 +640,8 @@ static PyObject* stria_itrminer_as_list(stria_ITRMiner *self) {
616640
}
617641
}
618642

619-
free(motif);
620-
release_matrix(matrix, self->extend_maxlen);
643+
free(self->motif);
644+
release_matrix(self->matrix, self->extend_maxlen);
621645
return itrs;
622646
}
623647

src/itr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ typedef struct {
5656
//maximal extend length
5757
int extend_maxlen;
5858

59+
//current motif sequence
60+
char* motif;
61+
62+
//dynamic alignment matrix
63+
int** matrix;
64+
5965
} stria_ITRMiner;
6066

6167
typedef struct {

src/ssr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static PyObject* stria_ssrminer_as_list(stria_SSRMiner *self) {
178178
int replen;
179179
int repeats;
180180
int length;
181-
char motif[7];
181+
char *motif = (char *)malloc(7);
182182

183183
for (Py_ssize_t i = 0; i < self->size; ++i) {
184184
if (self->seq[i] == 78) {
@@ -213,6 +213,7 @@ static PyObject* stria_ssrminer_as_list(stria_SSRMiner *self) {
213213
}
214214
}
215215

216+
free(motif);
216217
return ssrs;
217218
}
218219

0 commit comments

Comments
 (0)