Skip to content

Commit 9d96149

Browse files
committed
patched GSamReader::next() memory leak
1 parent 2bdb26f commit 9d96149

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

gclib/GSam.h

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,117 @@ class GSamRecord: public GSeg {
140140
~GSamRecord() {
141141
clear();
142142
}
143+
/*
144+
void print_cigar(bam1_t *al){
145+
for (uint8_t c=0;c<al->core.n_cigar;++c){
146+
uint32_t *cigar_full=bam_get_cigar(al);
147+
int opcode=bam_cigar_op(cigar_full[c]);
148+
int length=bam_cigar_oplen(cigar_full[c]);
149+
std::cout<<length<<bam_cigar_opchr(opcode);
150+
}
151+
std::cout<<std::endl;
152+
}
153+
154+
void print_seq(bam1_t *new_rec){
155+
int32_t qlen = new_rec->core.l_qseq;
156+
int8_t *buf = NULL;
157+
buf = static_cast<int8_t *>(realloc(buf, qlen+1));
158+
buf[qlen] = '\0';
159+
uint8_t* seq = bam_get_seq(new_rec);
160+
for (int i = 0; i < qlen; ++i)
161+
buf[i] = bam_seqi(seq, i);
162+
for (int i = 0; i < qlen; ++i) {
163+
buf[i] = seq_nt16_str[buf[i]];
164+
}
165+
std::string str_seq((char*)(char*)buf);
166+
std::cout<<str_seq<<std::endl;
167+
}
168+
*/
169+
// taken from samtools/bam_import.c
170+
static inline uint8_t * alloc_data(bam1_t *b, size_t size)
171+
{
172+
if (b->m_data < size)
173+
{
174+
b->m_data = size;
175+
kroundup32(b->m_data);
176+
b->data = (uint8_t*)realloc(b->data, b->m_data);
177+
}
178+
return b->data;
179+
}
180+
181+
bam1_t * bam_update(bam1_t * b,
182+
const size_t nbytes_old,
183+
const size_t nbytes_new,
184+
uint8_t * field_start){ // from pysam
185+
int d = nbytes_new - nbytes_old;
186+
int new_size;
187+
size_t nbytes_before;
188+
uint8_t * retval = NULL;
189+
190+
// no change
191+
if (d == 0)
192+
return b;
193+
194+
// new size of total data
195+
new_size = d + b->l_data;
196+
197+
// fields before field in data
198+
nbytes_before = field_start - b->data;
199+
/*
200+
if (b->l_data != 0)
201+
{
202+
assert(nbytes_before >= 0);
203+
assert(nbytes_before <= b->l_data);
204+
}
205+
*/
206+
// increase memory if required
207+
if (d > 0)
208+
{
209+
retval = alloc_data(b, new_size);
210+
if (retval == NULL)
211+
return NULL;
212+
field_start = b->data + nbytes_before;
213+
}
214+
215+
// move data after field to new location
216+
memmove(field_start + nbytes_new,
217+
field_start + nbytes_old,
218+
b->l_data - (nbytes_before + nbytes_old));
143219

220+
// adjust l_data
221+
b->l_data = new_size;
222+
223+
return b;
224+
}
225+
/*
226+
void replace_qname(int id){ // replace the name with an ID
227+
char * p = bam_get_qname(b);
228+
229+
std::string qname = std::to_string(id);
230+
int l = qname.size()+1;
231+
int l_extranul = 0;
232+
if (l % 4 != 0){
233+
l_extranul = 4 - l % 4;
234+
}
235+
236+
bam1_t * retval = bam_update(b,b->core.l_qname,l + l_extranul,(uint8_t*)p);
237+
if (retval == NULL){
238+
GError("Could not allocate memory");
239+
}
240+
241+
b->core.l_extranul = l_extranul;
242+
b->core.l_qname = l + l_extranul;
243+
244+
p = bam_get_qname(b);
245+
246+
strcpy(p,qname.c_str());
247+
uint16_t x = 0;
248+
249+
for (int x=l;x<l+l_extranul;x++){
250+
p[x] = '\0';
251+
}
252+
}
253+
*/
144254
void parse_error(const char* s) {
145255
GError("SAM parsing error: %s\n", s);
146256
}
@@ -381,6 +491,7 @@ class GSamReader {
381491
GSamRecord* bamrec=new GSamRecord(b, hdr, true);
382492
return bamrec;
383493
}
494+
bam_destroy1(b);
384495
return NULL;
385496
}
386497

0 commit comments

Comments
 (0)