究竟什么是<!> quot;断言<!>“;或者更具体地说,我如何摆脱错误。当我创建一个指向带有数据成员int x的类的指针向量,然后执行以下操作:

for(I=antiviral_data.begin();I<antiviral_data.end();I++)
{
    if((*I)->x>maxx)
    {
        antiviral_data.erase(I);
    }
}

运行程序,在x大于maxx并且使用.erase()之前我没有错误,此时我收到此错误:

  

Debug Assertion失败!

     

程序:...我的文档\ O.exe文件:   ... include \ vector Line:116

     

表达式:   (<!> QUOT;这 - GT <!>; <!> _Has_container()QUOT;,0)

     

有关您的计划的信息   可能会导致断言失败,请参阅   Visual C ++文档   断言。

     

(按“重试”调试应用程序)

     

[中止] [重试] [忽略]

另外,如果我尝试使用cout:

cout<<(*antiviral_data.begin())->x<<endl;

我收到此错误:

  

Debug Assertion失败!

     

程序:...我的文档\ O.exe文件:   ...包括\ vector Line:98

     

表达式:不是矢量迭代器   deferencable

     

有关您的计划的信息   可能会导致断言失败,请参阅   Visual C ++文档   断言。

     

(按“重试”调试应用程序)

     

[中止] [重试] [忽略]

有人可以告诉我为什么我不能使用载体中的任何数据,以及如何解决它?

另外:antiviral_data是一个指针向量,只有一个元素:

antiviral_data.push_back(new aX1(player.x,player.y,'>'));

如果有帮助的话。

有帮助吗?

解决方案

你得到断言的最可能的原因是你在擦除后增加了我。试试这个:

for(I=antiviral_data.begin();I!=antiviral_data.end();)
{
    if((*I)->x>maxx) I=antiviral_data.erase(I); else ++I;
}

另见 http://www.cppreference.com/wiki/stl/vector/擦除,在该页面上搜索无效迭代器

其他提示

断言通常是开发人员为调试和错误控制目的而输入的表达式 - 您使用不同的<!>“完整性检查<!>”;在你的代码中,如果没有达到检查,就让程序崩溃。

例如,假设你有一些代码可以将两个数字划分到某个地方。即使你总是期望除以非零,你也可以在除法之前断言,以防参数计算错误。如果断言失败,则意味着在某个地方出现故障。

断言通常只出现在代码中的调试版本中(如果使用visual C ++,则可以编译以进行调试和发布)。虽然在发布模式下进行编译会消除结果,但这是一个非常糟糕的主意,因为您仍然会出现错误并且结果可能非常糟糕。

在Vector的实现中(某些地方是标准的),特别是在第98行中,有一个断言。如果您可以访问向量代码,请查看断言是什么或调试到那一点。这可能表示向量实现或调用向量的代码中的错误。

您发布的内容为我们提供了一些有关正在发生的事情的提示,但如果您可以粘贴更多程序(包括定义矢量的位置),这将非常有用。

问题在于擦除调用。您正在迭代容器,同时从中删除元素。擦除后,迭代器变为无效。如果要从向量中删除特定值的元素,请使用remove_if算法擦除。这被称为擦除删除习语,并在Scott Meyer的Effective STL书中得到了很好的解释。您还可以参考此问题从矢量中删除元素以获取更多信息。

对于什么是断言以及为什么在代码中触发它,您已经有了几个很好的答案。现在,您可能需要考虑使用STL算法进行两次擦除。

namespace {
   struct exceeds : public std::unary_function< TheUnknownType*, bool >
   {
      exceeds_max( int max ) : maxx( max ) {}
      bool operator()( TheUnknownType* data ) {
         return data->x < max;
      } 
   private:
      int maxx;
   };
}
void your_function()
{
   std::vector< TheUnknownType* >::iterator new_end;
   new_end = std::remove_if( antiviral_data.begin(), antiviral_data.end(), exceeds(maxx) );
   antiviral_data.remove( new_end, antiviral_data.end() );
}

主要优点是在向量中擦除元素是一项昂贵的操作。对于每个被擦除的元素,从该位置到向量末尾的所有元素必须朝向开头移动一个位置。你擦除的第二个元素将强制从那里开始所有元素的第二次移动... STL remove_if 算法只执行一次移动到它们的最终位置,返回一个迭代器一个最后一个元素未删除元素。然后你可以执行一个单独的std :: vector <!> lt; <!> gt; :: remove,它不需要重新定位元素。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top