表达式:String iterator not dereferencable [英] Expression: String iterator not dereferencable

查看:1087
本文介绍了表达式: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆