为什么我的矢量代码断言? 到底什么是断言?

发布于 2024-07-19 08:13:05 字数 1187 浏览 4 评论 0原文

到底什么是“断言”,或者更具体地说,我如何消除错误。 当我创建一个指向带有数据成员 int x 的类的指针向量,然后执行以下操作:

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

并运行程序时,直到 x 大于 maxx 并且我使用 .erase() 时,我才会收到错误,此时我得到了这个错误:

调试断言失败!

程序:...我的文档\O.exe 文件: ...包括\向量行:116

表达式: (“这个->_Has_container()”,0)

有关您的程序如何进行的信息 可能会导致断言失败,请参阅 Visual C++ 文档 断言。

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

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

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

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

我收到此错误:

调试断言失败!

程序:...My Documents\O.exe 文件: ...包括\矢量线:98

表达式:向量迭代器不 可引用

有关您的程序如何进行的信息 可能会导致断言失败,请参阅 Visual C++ 文档 断言。

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

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

有人可以告诉我为什么我不能使用向量中的任何数据,以及如何修复它吗?

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

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

如果有帮助的话。

What exactly is an "assert", or more specifically, how do I get rid of an error. When I create a vector of pointers to a class with data member int x, and then do this:

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

And run the program, I get no errors until x is greater than maxx and I use .erase(), at which point I get this error:

Debug Assertion Failed!

Program: ...My Documents\O.exe File:
...include\vector Line: 116

Expression:
("this->_Has_container()",0)

For information on how your program
can cause an assertion failure, see
the Visual C++ documentation on
asserts.

(Press Retry to debug the application)

[Abort][Retry][Ignore]

Also, if I try to use cout:

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

I get this error:

Debug Assertion Failed!

Program: ...My Documents\O.exe File:
...include\vector Line: 98

Expression: vector iterator not
deferencable

For information on how your program
can cause an assertion failure, see
the Visual C++ documentation on
asserts.

(Press Retry to debug the application)

[Abort][Retry][Ignore]

Could somebody please tell me why I can't USE any of the data in the vector, and how to fix it?

ALSO: antiviral_data is a vector of pointers, with a single element:

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

If that helps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏夜暖风 2024-07-26 08:13:05

您得到断言的最可能原因是您在擦除后增加了 I。 请尝试以下操作:

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 /erase ,在该页面上搜索无效迭代器

The most probable reason why you get the assertion is that you increment I after an erase. Try this instead:

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

See also http://www.cppreference.com/wiki/stl/vector/erase , search for invalid iterators on that page.

叹倦 2024-07-26 08:13:05

断言通常是开发人员出于调试和错误控制目的而输入的表达式 - 您在代码中放置不同的“健全性检查”,如果未达到检查,则让它崩溃程序。

例如,假设您有一段代码要在某处将两个数字相除。 尽管您总是期望除以非零,但您在除法之前放置了断言,以防参数计算错误。 如果断言失败,则意味着前面的某个地方发生了故障。

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

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

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

An assert is typically an expression entered by a developer for debug and error control purposes - you put different "sanity checks" in your code, and have it crash the program if the check is not reached.

For example, imagine you had code that was going to divide two numbers somewhere down the road. Even though you always expect a division by non-zero, you put at assert before the division in case an argument got miscalculated. If the assert fails, it means somewhere up the road there was a failure.

Assertions typically appear only in the debug version in the code (If you use visual C++ you can compile for debug and release). While compiling in release mode would eliminate the results, it is a very bad idea, since you would still have an error and probably really bad results.

Somewhere in the implementation of Vector (is it standard), and speciifcally in line 98, there is an assert. If you have access to the vector code, look to see what the assert is or debug up to that point. This could indicate an error in the vector implementation, or in the code that calls vector.

The stuff you posted gives us some hints of what's going on, but it would be useful if you could paste more of the program, including where the vectors are defined.

神经大条 2024-07-26 08:13:05

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

The problem is with erase call. You are iterating through a container and at the same time erasing elements from it. After doing an erase, your iterator becomes invalid. If you want to remove elements of a particular value from a vector use erase with remove_if algorithm. This is known as a erase-remove idiom and explained very well in Scott Meyer's Effective STL book. You can also refer to this question Erasing elements from a vector for more information.

伤感在游骋 2024-07-26 08:13:05

关于什么是断言以及为什么它在代码中被触发,您已经有了一些很好的答案。 现在,您可能需要考虑使用 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 算法仅执行一次移动到最终位置,返回一个迭代器过去 em> 最后一个未删除的元素。 然后,您可以执行一个不需要重新定位元素的 std::vector<>::remove 操作。

You already have a couple of good answers about what is an assertion and why it is being triggered in your code. Now, you may want to consider using STL algorithms for a two pass erasure.

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() );
}

The main advantage is that erasing elements in a vector is an expensive operation. For each element erased, all elements from that position to the end of the vector must be moved one position towards the beginning. The second element you erase will force a second move of all the elements from there on... The STL remove_if algorithm performs the moves only once to their final position returning an iterator one past the last element not removed element. Then you can perform one single std::vector<>::remove that will not need to relocate elements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文