我在尝试解析大文本文件时遇到了分段错误。该文件包含91 529个mRNA转录本和有关这些转录本的详细信息。我已经创建了一个RefSeqTranscript对象来获取这些细节。当我解析文件时,我创建了这些对象的列表,并开始将详细信息放入这些列表中。它适用于前1829个成绩单,然后因分段错误而崩溃。我正在运行的方法是:
void TranscriptGBFFParser::ParseFile(list<RefSeqTranscript> &transcripts, const char* filepath)
{
cout << "Parsing " << filepath << "..." << endl;
ifstream infile;
infile.open(filepath);
int num = 0;
RefSeqTranscript *transcript = new RefSeqTranscript();
for(string line; getline(infile, line); )
{
in.clear();
in.str(line);
if (boost::starts_with(line, "LOCUS"))
{
if((*transcript).transcriptRefSeqAcc.size() > 0)
{
cout << (*transcript).transcriptRefSeqAcc << ":" << (*transcript).gi << ":" << (*transcript).gene.geneName << ":" << ++num << endl;
transcripts.push_back(*transcript);
delete transcript;
RefSeqTranscript *transcript = new RefSeqTranscript();
}
}
else if (boost::starts_with(line, " var"))
{
TranscriptVariation variant;
(*transcript).variations.push_back(variant);
}
//Store the definition of the transcript in the description attribute
else if (boost::starts_with(line, "DEFINITION"))
{
(*transcript).description = line.substr(12);
for(line; getline(infile, line); )
{
if(boost::starts_with(line, "ACCESSION "))
break;
(*transcript).description += line.substr(12);
}
}
//The accession number and GI number are obtained from the VERSION line
else if (boost::starts_with(line, "VERSION"))
{
string versions = line.substr(12);
vector<string> strs;
boost::split(strs, versions, boost::is_any_of( " GI:" ), boost::token_compress_on);
boost::trim_left(strs[0]);
(*transcript).transcriptRefSeqAcc = strs[0];
(*transcript).gi = atoi(strs[1].c_str());
}
//Gene information is obtained from the "gene" sections of each transcript
else if (boost::starts_with(line, " gene"))
{
for(line; getline(infile, line); )
{
if(boost::starts_with(line.substr(21), "/gene="))
{
Gene *gene = new Gene();
string name = line.substr(27);
Utilities::trim(name, '\"');
(*gene).geneName = name;
(*transcript).gene = *gene;
delete gene;
break;
}
}
(*transcript).gene.geneID = 0;
}
else if (boost::starts_with(line, " CDS"))
{
(*transcript).proteinRefSeqAcc = "";
}
else if (boost::starts_with(line, "ORIGIN"))
{
(*transcript).sequence = "";
}
}
cout << (*transcript).transcriptRefSeqAcc << ":" << (*transcript).gi << ":" << (*transcript).gene.geneName << endl;
transcripts.push_back(*transcript);
delete transcript;
cout << "No. transcripts: " << transcripts.size() << endl;
cout << flush;
infile.close();
cout << "Finished parsing " << filepath << "." << endl;
}
我是C ++的新手,并且对如何使用指针等没有很好的理解,所以我猜我可能在那里做错了。我不明白为什么它会在切断之前用于近2000个物体。
我正在解析的文件是2.1 GB,包含大约44 000 000行,因此任何关于如何提高效率的提示也会受到高度赞赏。
答案 0 :(得分:0)
这可能不是唯一的答案,但你有泄漏......
if (boost::starts_with(line, "LOCUS"))
{
if((*transcript).transcriptRefSeqAcc.size() > 0)
{
cout << (*transcript).transcriptRefSeqAcc << ":" << (*transcript).gi << ":" << (*transcript).gene.geneName << ":" << ++num << endl;
transcripts.push_back(*transcript);
delete transcript;
// LEAK!
RefSeqTranscript *transcript = new RefSeqTranscript();
}
}
你可能意味着:
transcript = new RefSeqTranscript();
答案 1 :(得分:0)
除非您提供更多详细信息,否则很难说出具体内容:
但我建议你做一些改进:
RefSeqTranscript *transcript
; Gene *gene
; 你有一个错误:
delete transcript;
RefSeqTranscript *transcript = new RefSeqTranscript();
由于您已经在循环体外声明了成绩单,因此您可以使用相同名称的新变量隐藏它。这会导致内存泄漏,而且,您删除外部脚本,不要用任何内容替换它。所以,你可能会在下一次迭代中遇到崩溃。