Skip to content

Commit ed0ac17

Browse files
committed
Fix bugs that cause memory leak when reading fasta files
1 parent 2b73e3f commit ed0ac17

5 files changed

Lines changed: 70 additions & 53 deletions

File tree

blatSrc/blat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ void* performSearch(void* args)
408408
maskHash, &totalSize, &count, gvo);
409409
}
410410
free(seq.name);
411+
faFreeFastBuf(&faFastBuf, &faFastBufSize);
411412
}
412413
}
413414
if (showStatus)
@@ -562,6 +563,7 @@ void* performBigblat(void* args)
562563
gfOutputQuery(gvo, out);
563564
}
564565
free(qSeq.name);
566+
faFreeFastBuf(&faFastBuf, &faFastBufSize);
565567
}
566568
}
567569

@@ -933,6 +935,7 @@ int main(int argc, char *argv[])
933935
lineFileSeek(lf[i], tlf->bufOffsetInFile + tlf->lineStart, SEEK_SET);
934936
}
935937
lineFileClose(&tlf);
938+
faFreeFastBuf(&faFastBuf, &faFastBufSize);
936939

937940

938941

inc/fa.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* This file is copyright 2002 Jim Kent, but license is hereby
44
* granted for all use - public, private or commercial. */
55

6-
/* Modified by Meng Wang. 2012-2014 */
6+
/* Modified by Meng Wang. 2012-2015 */
77

88
#ifndef FA_H
99
#define FA_H
@@ -25,22 +25,22 @@ aaSeq *faReadAa(char *fileName);
2525
bioSeq *faReadSeq(char *fileName, boolean isDna);
2626
/* Read a dna or protein sequence. */
2727

28-
struct dnaSeq *faReadAllDna(char *fileName);
28+
struct dnaSeq *faReadAllDna(char *fileName, DNA **faFastBuf, unsigned *faFastBufSize);
2929
/* Return list of all DNA sequences in FA file. */
3030

31-
struct dnaSeq *faReadAllPep(char *fileName);
31+
struct dnaSeq *faReadAllPep(char *fileName, DNA **faFastBuf, unsigned *faFastBufSize);
3232
/* Return list of all Peptide sequences in FA file. */
3333

34-
struct dnaSeq *faReadAllSeq(char *fileName, boolean isDna);
34+
struct dnaSeq *faReadAllSeq(char *fileName, boolean isDna, DNA **faFastBuf, unsigned *faFastBufSize);
3535
/* Return list of all sequences in FA file. */
3636

37-
struct dnaSeq *faReadAllMixed(char *fileName);
37+
struct dnaSeq *faReadAllMixed(char *fileName, DNA **faFastBuf, unsigned *faFastBufSize);
3838
/* Read in mixed case fasta file, preserving case. */
3939

40-
struct hash *faReadAllIntoHash(char *fileName, enum dnaCase dnaCase);
40+
struct hash *faReadAllIntoHash(char *fileName, enum dnaCase dnaCase, DNA **faFastBuf, unsigned *faFastBufSize);
4141
/* Return hash of all sequences in FA file. */
4242

43-
struct dnaSeq *faReadAllMixedInLf(struct lineFile *lf);
43+
struct dnaSeq *faReadAllMixedInLf(struct lineFile *lf, DNA **faFastBuf, unsigned *faFastBufSize);
4444
/* Read in mixed case sequence from open fasta file. */
4545

4646
struct dnaSeq *faReadOneDnaSeq(FILE *f, char *name, boolean mustStartWithSign);
@@ -85,21 +85,25 @@ bioSeq *faSeqListFromMemTextRaw(char *text);
8585
/* Convert fa's in memory into list of dnaSeqs without
8686
* converting chars to N's. */
8787

88-
boolean faFastReadNext(FILE *f, DNA **retDna, int *retSize, char **retName);
88+
boolean faFastReadNext(FILE *f, DNA **retDna, int *retSize, char **retName,
89+
DNA **faFastBuf, unsigned *faFastBufSize);
8990
/* Read in next FA entry as fast as we can. Return FALSE at EOF.
9091
* The returned DNA and name will be overwritten by the next call
9192
* to this function. */
9293

93-
boolean faSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName);
94+
boolean faSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName,
95+
DNA **faFastBuf, unsigned *faFastBufSize);
9496
/* Read in next FA entry as fast as we can. Faster than that old,
9597
* pokey faFastReadNext. Return FALSE at EOF.
9698
* The returned DNA and name will be overwritten by the next call
9799
* to this function. */
98100

99-
boolean faPepSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName);
101+
boolean faPepSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName,
102+
DNA **faFastBuf, unsigned *faFastBufSize);
100103
/* Read in next peptide FA entry as fast as we can. */
101104

102-
boolean faSomeSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName, boolean isDna);
105+
boolean faSomeSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName, boolean isDna,
106+
DNA **faFastBuf, unsigned *faFastBufSize);
103107
/* Read in DNA or Peptide FA record. */
104108

105109
boolean faMixedSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName, DNA **faFastBuf, unsigned *faFastBufSize);
@@ -116,7 +120,7 @@ void faToDna(char *poly, int size);
116120
* any strange characters to 'n'. Does not change size.
117121
* of sequence. */
118122

119-
void faFreeFastBuf();
123+
void faFreeFastBuf(DNA **faFastBuf, unsigned *faFastBufSize);
120124
/* Free up buffers used in fa fast and speedreading. */
121125

122126
void faWrite(char *fileName, char *startLine, DNA *dna, int dnaSize);

jkOwnLib/genoFind.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,11 @@ int oocCount = 0;
19921992
char *inName;
19931993
FILE *f = mustOpen(outName, "w");
19941994

1995+
1996+
unsigned faFastBufSize = 0;
1997+
DNA *faFastBuf;
1998+
1999+
19952000
if (gf->segSize > 0)
19962001
errAbort("Don't yet know how to make ooc files for large tile sizes.");
19972002
for (i=0; i<fileCount; ++i)
@@ -2010,7 +2015,8 @@ for (i=0; i<fileCount; ++i)
20102015
}
20112016
else
20122017
{
2013-
seqList = faReadAllSeq(inName, tType != gftProt);
2018+
seqList = faReadAllSeq(inName, tType != gftProt, &faFastBuf, &faFastBufSize);
2019+
faFreeFastBuf(&faFastBuf, &faFastBufSize);
20142020
}
20152021
printf("Counting %s\n", inName);
20162022
for (seq = seqList; seq != NULL; seq = seq->next)

jkOwnLib/gfClientLib.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
* genoFind use. */
33
/* Copyright 2001-2005 Jim Kent. All rights reserved. */
44

5+
/* Modified by Meng Wang. 2012-2015 */
6+
7+
58
#include "common.h"
69
#include "hash.h"
710
#include "linefile.h"
@@ -173,6 +176,9 @@ char *fileName;
173176
bioSeq *seqList = NULL, *seq;
174177
boolean doMask = (maskType != NULL);
175178

179+
unsigned faFastBufSize = 0;
180+
DNA *faFastBuf;
181+
176182
for (i=0; i<fileCount; ++i)
177183
{
178184
struct dnaSeq *list = NULL, sseq;
@@ -183,9 +189,11 @@ for (i=0; i<fileCount; ++i)
183189
else if (twoBitIsSpec(fileName))
184190
list = twoBitLoadAll(fileName);
185191
else if (isProt)
186-
list = faReadAllPep(fileName);
192+
list = faReadAllPep(fileName, &faFastBuf, &faFastBufSize);
187193
else
188-
list = faReadAllMixed(fileName);
194+
list = faReadAllMixed(fileName, &faFastBuf, &faFastBufSize);
195+
faFreeFastBuf(&faFastBuf, &faFastBufSize);
196+
189197

190198
/* If necessary mask sequence from file. */
191199
if (doMask)

lib/fa.c

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,7 @@ struct dnaSeq *faReadAa(char *fileName)
295295
return faReadSeq(fileName, FALSE);
296296
}
297297

298-
static unsigned faFastBufSize = 0;
299-
static DNA *faFastBuf;
298+
300299

301300
static void expandFaFastBuf(int bufPos, int minExp, DNA **faFastBuf, unsigned *faFastBufSize)
302301
/* Make faFastBuf bigger. */
@@ -328,15 +327,15 @@ static void expandFaFastBuf(int bufPos, int minExp, DNA **faFastBuf, unsigned *f
328327
}
329328
}
330329

331-
void faFreeFastBuf()
330+
void faFreeFastBuf(DNA **faFastBuf, unsigned *faFastBufSize)
332331
/* Free up buffers used in fa fast and speedreading. */
333332
{
334-
freez(&faFastBuf);
335-
faFastBufSize = 0;
333+
freez(faFastBuf);
334+
*faFastBufSize = 0;
336335
}
337336

338337

339-
boolean faFastReadNext(FILE *f, DNA **retDna, int *retSize, char **retName)
338+
boolean faFastReadNext(FILE *f, DNA **retDna, int *retSize, char **retName, DNA **faFastBuf, unsigned *faFastBufSize)
340339
/* Read in next FA entry as fast as we can. Return FALSE at EOF.
341340
* The returned DNA and name will be overwritten by the next call
342341
* to this function. */
@@ -347,8 +346,6 @@ boolean faFastReadNext(FILE *f, DNA **retDna, int *retSize, char **retName)
347346
int nameIx = 0;
348347
boolean gotSpace = FALSE;
349348

350-
unsigned faFastBufSize = 0;
351-
DNA *faFastBuf;
352349

353350
/* Seek to next '\n' and save first word as name. */
354351
dnaUtilOpen();
@@ -389,8 +386,8 @@ boolean faFastReadNext(FILE *f, DNA **retDna, int *retSize, char **retName)
389386
if (c == 0) c = 'n';
390387
}
391388
if (bufIx >= faFastBufSize)
392-
expandFaFastBuf(bufIx, 0, &faFastBuf, &faFastBufSize);
393-
faFastBuf[bufIx++] = c;
389+
expandFaFastBuf(bufIx, 0, faFastBuf, faFastBufSize);
390+
*faFastBuf[bufIx++] = c;
394391
if (c == 0)
395392
{
396393
*retDna = faFastBuf;
@@ -532,15 +529,14 @@ for (i=0; i<size; ++i)
532529
}
533530
}
534531

535-
boolean faSomeSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName, boolean isDna)
532+
boolean faSomeSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName, boolean isDna,
533+
DNA **faFastBuf, unsigned *faFastBufSize)
536534
/* Read in DNA or Peptide FA record. */
537535
{
538536
char *poly;
539537
int size;
540-
unsigned faFastBufSize = 0;
541-
DNA *faFastBuf;
542538

543-
if (!faMixedSpeedReadNext(lf, retDna, retSize, retName, &faFastBuf, &faFastBufSize))
539+
if (!faMixedSpeedReadNext(lf, retDna, retSize, retName, faFastBuf, faFastBufSize))
544540
return FALSE;
545541
size = *retSize;
546542
poly = *retDna;
@@ -551,23 +547,25 @@ boolean faSomeSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, cha
551547
return TRUE;
552548
}
553549

554-
boolean faPepSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName)
550+
boolean faPepSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName,
551+
DNA **faFastBuf, unsigned *faFastBufSize)
555552
/* Read in next peptide FA entry as fast as we can. */
556553
{
557-
return faSomeSpeedReadNext(lf, retDna, retSize, retName, FALSE);
554+
return faSomeSpeedReadNext(lf, retDna, retSize, retName, FALSE, faFastBuf, faFastBufSize);
558555
}
559556

560-
boolean faSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName)
557+
boolean faSpeedReadNext(struct lineFile *lf, DNA **retDna, int *retSize, char **retName,
558+
DNA **faFastBuf, unsigned *faFastBufSize)
561559
/* Read in next FA entry as fast as we can. Faster than that old,
562560
* pokey faFastReadNext. Return FALSE at EOF.
563561
* The returned DNA and name will be overwritten by the next call
564562
* to this function. */
565563
{
566-
return faSomeSpeedReadNext(lf, retDna, retSize, retName, TRUE);
564+
return faSomeSpeedReadNext(lf, retDna, retSize, retName, TRUE, faFastBuf, faFastBufSize);
567565
}
568566

569567
static struct dnaSeq *faReadAllMixableInLf(struct lineFile *lf,
570-
boolean isDna, boolean mixed)
568+
boolean isDna, boolean mixed, DNA **faFastBuf, unsigned *faFastBufSize)
571569
/* Return list of all sequences from open fa file.
572570
* Mixed case parameter overrides isDna. If mixed is false then
573571
* will return DNA in lower case and non-DNA in upper case. */
@@ -578,15 +576,13 @@ static struct dnaSeq *faReadAllMixableInLf(struct lineFile *lf,
578576
char *name=buf;
579577
int size;
580578
boolean ok;
581-
unsigned faFastBufSize = 0;
582-
DNA *faFastBuf;
583579

584580
for (;;)
585581
{
586582
if (mixed)
587-
ok = faMixedSpeedReadNext(lf, &dna, &size, &name, &faFastBuf, &faFastBufSize);
583+
ok = faMixedSpeedReadNext(lf, &dna, &size, &name, faFastBuf, faFastBufSize);
588584
else
589-
ok = faSomeSpeedReadNext(lf, &dna, &size, &name, isDna);
585+
ok = faSomeSpeedReadNext(lf, &dna, &size, &name, isDna, faFastBuf, faFastBufSize);
590586
if (!ok)
591587
break;
592588
AllocVar(seq);
@@ -596,27 +592,27 @@ static struct dnaSeq *faReadAllMixableInLf(struct lineFile *lf,
596592
slAddHead(&seqList, seq);
597593
}
598594
slReverse(&seqList);
599-
faFreeFastBuf(&faFastBuf, &faFastBufSize);
600595
return seqList;
601596
}
602597

603-
static struct dnaSeq *faReadAllSeqMixable(char *fileName, boolean isDna, boolean mixed)
598+
static struct dnaSeq *faReadAllSeqMixable(char *fileName, boolean isDna, boolean mixed,
599+
DNA **faFastBuf, unsigned *faFastBufSize)
604600
/* Return list of all sequences in FA file.
605601
* Mixed case parameter overrides isDna. If mixed is false then
606602
* will return DNA in lower case and non-DNA in upper case. */
607603
{
608604
struct lineFile *lf = lineFileOpen(fileName, FALSE);
609-
struct dnaSeq *seqList = faReadAllMixableInLf(lf, isDna, mixed);
605+
struct dnaSeq *seqList = faReadAllMixableInLf(lf, isDna, mixed, faFastBuf, faFastBufSize);
610606
lineFileClose(&lf);
611607
return seqList;
612608
}
613609

614-
struct hash *faReadAllIntoHash(char *fileName, enum dnaCase dnaCase)
610+
struct hash *faReadAllIntoHash(char *fileName, enum dnaCase dnaCase, DNA **faFastBuf, unsigned *faFastBufSize)
615611
/* Return hash of all sequences in FA file. */
616612
{
617613
boolean isDna = (dnaCase == dnaLower);
618614
boolean isMixed = (dnaCase == dnaMixed);
619-
struct dnaSeq *seqList = faReadAllSeqMixable(fileName, isDna, isMixed);
615+
struct dnaSeq *seqList = faReadAllSeqMixable(fileName, isDna, isMixed, faFastBuf, faFastBufSize);
620616
struct hash *hash = hashNew(18);
621617
struct dnaSeq *seq;
622618
for (seq = seqList; seq != NULL; seq = seq->next)
@@ -629,32 +625,32 @@ return hash;
629625
}
630626

631627

632-
struct dnaSeq *faReadAllSeq(char *fileName, boolean isDna)
628+
struct dnaSeq *faReadAllSeq(char *fileName, boolean isDna, DNA **faFastBuf, unsigned *faFastBufSize)
633629
/* Return list of all sequences in FA file. */
634630
{
635-
return faReadAllSeqMixable(fileName, isDna, FALSE);
631+
return faReadAllSeqMixable(fileName, isDna, FALSE, faFastBuf, faFastBufSize);
636632
}
637633

638-
struct dnaSeq *faReadAllDna(char *fileName)
634+
struct dnaSeq *faReadAllDna(char *fileName, DNA **faFastBuf, unsigned *faFastBufSize)
639635
/* Return list of all DNA sequences in FA file. */
640636
{
641-
return faReadAllSeq(fileName, TRUE);
637+
return faReadAllSeq(fileName, TRUE, faFastBuf, faFastBufSize);
642638
}
643639

644-
struct dnaSeq *faReadAllPep(char *fileName)
640+
struct dnaSeq *faReadAllPep(char *fileName, DNA **faFastBuf, unsigned *faFastBufSize)
645641
/* Return list of all peptide sequences in FA file. */
646642
{
647-
return faReadAllSeq(fileName, FALSE);
643+
return faReadAllSeq(fileName, FALSE, faFastBuf, faFastBufSize);
648644
}
649645

650-
struct dnaSeq *faReadAllMixed(char *fileName)
646+
struct dnaSeq *faReadAllMixed(char *fileName, DNA **faFastBuf, unsigned *faFastBufSize)
651647
/* Read in mixed case fasta file, preserving case. */
652648
{
653-
return faReadAllSeqMixable(fileName, FALSE, TRUE);
649+
return faReadAllSeqMixable(fileName, FALSE, TRUE, faFastBuf, faFastBufSize);
654650
}
655651

656-
struct dnaSeq *faReadAllMixedInLf(struct lineFile *lf)
652+
struct dnaSeq *faReadAllMixedInLf(struct lineFile *lf, DNA **faFastBuf, unsigned *faFastBufSize)
657653
/* Read in mixed case sequence from open fasta file. */
658654
{
659-
return faReadAllMixableInLf(lf, FALSE, TRUE);
655+
return faReadAllMixableInLf(lf, FALSE, TRUE, faFastBuf, faFastBufSize);
660656
}

0 commit comments

Comments
 (0)