C++正在混合我的字符串?
我有这个我自己写的非常简单的C++函数。
它应该从我的字符串中去掉' - '字符。
下面的代码C++正在混合我的字符串?
char* FastaManager::stripAlignment(char *seq, int seqLength){
char newSeq[seqLength];
int j=0;
for (int i=0; i<seqLength; i++) {
if (seq[i] != '-') {
newSeq[j++]=seq[i];
}
}
char *retSeq = (char*)malloc((--j)*sizeof(char));
for (int i=0; i<j; i++) {
retSeq[i]=newSeq[i];
}
retSeq[j+1]='\0'; //WTF it keeps reading from memory without this
return retSeq;
}
我觉得评论是不言而喻的。
我不知道为什么,但是当我启动该程序,并打印出结果,我得到的东西像
'stripped_sequence''original_sequence'
但是,如果我尝试调试代码,看看是否有什么错,流程恰到好处,并最终返回正确的剥离序列。
我试图打印出两个变量的记忆,这里是存储器中的读数
记忆序列:http://i.stack.imgur.com/dHI8k.png
内存*序列:http://i.stack.imgur.com/UqVkX.png
内存retSeq:http://i.stack.imgur.com/o9uvI.png
内存* retSeq:http://i.stack.imgur.com/ioFsu.png
(不能包括因为垃圾邮件过滤器,遗憾的链接/图片)
这是我使用的是打印出来的字符串
for (int i=0; i<atoi(argv[2]); i++) {
char *seq;
if (usingStructure) {
seq = fm.generateSequenceWithStructure(structure);
}else{
seq = fm.generateSequenceFromProfile();
}
cout<<">Sequence "<<i+1<<": "<<seq<<endl;
}
现在的代码,我也实在没有什么回事想法上。
发生这种情况是因为您将C字符串的终止零置于分配空间之外。您应该在字符串副本的末尾分配一个额外的字符,并在那里添加'\0'
。或者更好的是,你应该使用std::string
。
char *retSeq = (char*)malloc((j+1)*sizeof(char));
for (int i=0; i<j; i++) {
retSeq[i]=newSeq[i];
}
retSeq[j]='\0';
it keeps reading from memory without this
这是由设计:C字符串是零结尾。 '\0'
向C中的字符串例程发送信号,表示已到达字符串的末尾。使用C字符串时,C++中也存在相同的约定。
谢谢,你给我我正在寻找的答案! – XelharK 2012-02-13 11:41:22
@dasblinkenlight您的示例代码可以通过使用strncpy缩短一点。 – 2012-02-13 11:52:37
@MrLister这主要是OP的代码,来自帖子的第10..14行。我所做的只是稍微纠正一下,以避免错误:删除'--',在一个地方添加了'+ 1',并在另一个地方删除了'+ 1'。我明白它可以被优化,但我想尽可能地保持原来的状态。 – dasblinkenlight 2012-02-13 11:58:29
如果你可以使用的std :: string,只要做到这一点:
std::string FastaManager::stripAlignment(const std::string& str)
{
std::string result(str);
result.erase(std::remove(result.begin(), result.end(), '-'), result.end());
return result;
}
这就是所谓的 “erase-remove idiom”。
我个人认为,除非你有,否则真的很好的理由你最好关闭使用std::string
:
std::string FastaManager::stripAlignment(std::string value)
{
value.erase(std::remove(value.begin(), value.end(), value.begin(), '-'), value.end());
return value;
}
当您使用您需要认识到,他们是空终止的C字符串:C字符串达到找到的第一个空字符。使用您发布的代码时,您在分配'j'元素时引入了超出范围的分配,并且您分配给retSeq[j + 1]
,这是字符串末尾的两个字符(无论如何,您的意思是retSeq[j] = 0;
)。
你可以使用std :: string而不是char *吗? – 2012-02-13 11:29:05
当然,我想..但我想弄清楚这里发生了什么! – XelharK 2012-02-13 11:32:08
这不是有效的标准C++。标准C++不提供可变长度数组。 – sellibitze 2012-02-13 11:40:12