表达式:String iterator not dereferencable [英] Expression: String iterator not dereferencable
问题描述
我很难在C ++中使用std :: string :: iterators。这个代码编译良好(仍然没有得到正确的输出,但这是我的错:TODO,修复算法)在Dev-C ++,我不会得到运行时错误。错误是在Visual Studio Express 2008 C ++,其中我得到一个错误指向< xstring>:Expression:string iterator not dereferencable,并且指向< xstring>文件。
我的调试告诉我,我可能试图去引用句子输入的结尾,但我看不到在哪里。
std :: string wordWrap(std :: string sentence,int width)
{
std :: string :: iterator it = sentence.begin();
//记住下一个字的长度
int nextWordLength = 0;
int distanceFromWidth = width;
while(it< sentence.end())
{
while(* it!=''&& it!= sentence.end())
{
nextWordLength ++;
distanceFromWidth--;
it ++;
}
if(nextWordLength> distanceFromWidth)
{
* it ='\\\
';
distanceFromWidth = width;
nextWordLength = 0;
}
//跳过空格
it ++;
}
return语句
}
()on iterators,not operator<():
while(it!= sentence.end())
其次, while(* it!=''&& it!= sentence.end())
做一些与迭代器,比检查迭代器是否有效。相反,您应该先检查它是否有效:
while(it!= sentence.end()&& !='')
第三,你应该使用++迭代器over迭代器++,虽然这与崩溃无关。
第四,主要问题在这里:
* it ='\\\
'
由于前面的检查, while(it!= sentence.end )
,可以在结束时达到迭代器取消引用。修复是这样做的:
if(it!= sentence.end()&&&< nextWordLength> distanceFromWidth)
<
修复后上一个问题,现在唯一的问题是这个:
//跳过空格
++ it;
这假设你正在跳过的字符实际上是一个空格。使用此字符串运行此函数:
一个测试字符串//< - space at end
p>
它会成功;它跳过空格,将迭代器放在 end()
,循环退出并成功。
但是,没有空间,它会崩溃,因为你已经到了结束,并跳过了结束。要修复,请添加检查:
//跳过空格
if(it!= sentence.end )
{
++ it;
}
产生此最终代码:
std :: string wordWrap(std :: string sentence,int width)
{
std :: string :: iterator it = sentence.begin();
//记住下一个字的长度
int nextWordLength = 0;
int distanceFromWidth = width;
while(it!= sentence.end())
{
while(it!= sentence.end()&& * it!=' b $ b {
nextWordLength ++;
distanceFromWidth--;
++ it;
}
if(it!= sentence.end()&&&< nextWordLength> distanceFromWidth)
{
* it ='\\\
'
distanceFromWidth = width;
nextWordLength = 0;
}
//跳过空格
if(it!= sentence.end())
{
++ it;
}
}
返回句子;
}
您可能会注意到这似乎有很多冗余检查。这可以修复:
std :: string wordWrap(std :: string sentence,int width)
{
std :: string :: iterator it = sentence.begin();
//记住下一个字的长度
int nextWordLength = 0;
int distanceFromWidth = width;
while(it!= sentence.end())
{
while(* it!='')
{
nextWordLength ++;
distanceFromWidth--;
++ it;
//检查是否完成
if(it == sentence.end())
{
return sentence;
}
}
if(nextWordLength> distanceFromWidth)
{
* it ='\\\
';
distanceFromWidth = width;
nextWordLength = 0;
}
//跳过空格
++ it;
}
return sentence;
}
希望这会有帮助!
I'm having a hard time using std::string::iterators in C++. This code compiles fine (still not getting correct output, but that's my fault: TODO, fix algorithm) in Dev-C++, and I don't get runtime errors. The error is with Visual Studio Express 2008 C++, where I'm getting an error pointing to < xstring>: "Expression: string iterator not dereferencable," and points to line 112 of the < xstring> file.
My debugging tells me I might be trying to dereference past the end of the sentence input, but I can't see where. Can anyone shed some light?
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it < sentence.end())
{
while (*it != ' ' && it != sentence.end())
{
nextWordLength++;
distanceFromWidth--;
it++;
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
it++;
}
return sentence;
}
Firstly, use operator!=() on iterators, not operator<():
while (it != sentence.end())
Secondly, this is backwards: while (*it != ' ' && it != sentence.end())
You do something with the iterator, than check if the iterator is valid. Rather, you should check if it's valid first:
while (it != sentence.end() && *it != ' ')
Thirdly, you should use ++iterator over iterator++, though this isn't related to your crashing.
Fourth, a main issue is here:
*it = '\n';
Because of the preceeding check, while (it != sentence.end()
, it's possible to reach that iterator dereference while being at the end. A fix would be to do this:
if (it != sentence.end() && nextWordLength > distanceFromWidth)
So now if you have reached the end, you stop.
After fixing the previous issue, now the only problem is this:
//skip the space
++it;
This assumes that the character you are skipping is in fact a space. But what about the end of the string? Run this function with this string:
"a test string " // <- space at end
And it will succeed; it skips the space, putting the iterator at end()
, the loop exits and success.
However, without the space it will crash, because you have reached the end, and are skipping past the end. To fix, add a check:
//skip the space
if (it != sentence.end())
{
++it;
}
Resulting in this final code:
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (it != sentence.end() && *it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
}
if (it != sentence.end() && nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
if (it != sentence.end())
{
++it;
}
}
return sentence;
}
You might notice this seems like it has a lot of redundant checks. This can be fixed:
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (*it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
// check if done
if (it == sentence.end())
{
return sentence;
}
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
++it;
}
return sentence;
}
Hopefully that helps!
这篇关于表达式:String iterator not dereferencable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!