【问题标题】:Assertion fails/Exceptions for STL断言失败/STL 异常
【发布时间】:2011-09-16 17:43:33
【问题描述】:

假设我有一个空列表 L。目前如果我运行 L.front(),它将愉快地执行返回一个垃圾值。有没有我可以打开的选项,这样执行它会引发异常或导致断言失败?

谢谢

【问题讨论】:

  • 这取决于您使用的 STL 实现。请提供更多详细信息。
  • g++ 4..6。我接受了 kert 的回答,因为它提供了 MSVC 和 g++ 的详细信息

标签: c++ stl standard-library


【解决方案1】:

如果您使用的是 Visual C++ 2010(可能还有更早的版本),那么您可以使用以下两个宏启用安全 SCL 和迭代器调试:

#define _SECURE_SCL 1
#define _HAS_ITERATOR_DEBUGGING 1

其他标准库可能也有。

编辑:正如建议的那样,VC2010 中有一个宏,即_ITERATOR_DEBUG_LEVEL,它有 3 个级别,定义如下:

#if _HAS_ITERATOR_DEBUGGING
    #define _ITERATOR_DEBUG_LEVEL 2
#elif _SECURE_SCL
    #define _ITERATOR_DEBUG_LEVEL 1
#else
    #define _ITERATOR_DEBUG_LEVEL 0
#endif

【讨论】:

  • 实际上,这些是 VC++ 2005 和 2008 的宏。对于 VC++ 2010,它们已被单个宏 _ITERATOR_DEBUG_LEVEL 替换。 (是的,我意识到 MSDN 没有提到这一点。)
  • 请不要自己定义这些宏。让它们正确很难Stephen Lavavej also discourages this。另外,VS2010 有_ITERATOR_DEBUG_LEVEL。在调试模式下,它设置为2,即完全调试。您可以重新定义 那个 宏,但请让另一个保持原样。
  • @Xeo:我不喜欢弄乱宏,但有时你必须这样做。例如,标准不禁止对不使用的无效迭代器求值,因此&*container.end(); 是一个非常好的表达式,但除非您禁用它,否则它会导致 VC 代码因 SCL 异常而崩溃。
  • @Gene :你为什么认为&*container.end(); 是有效的?取消引用任何结束迭代器都是非法的。
  • @Gene:@ildjarn 说了什么以及你为什么要这么做?!
【解决方案2】:

一些标准库确实提供了这样的选项。您需要查阅特定实现/编译器的文档和/或代码,以确定其特性以及如何启用它。

或者,您可以使用 valgrind 或 Purify 之类的内存检查器,而不是在库级别进行。

【讨论】:

    【解决方案3】:

    使用empty() 检查列表是否为空。 size() 在这里不好,因为它可能具有线性运行时。在Effective STL 中查看更多详细信息。 empty() 具有恒定的运行时间,这是一种标准方式。

    【讨论】:

      【解决方案4】:

      【讨论】:

      • 关于 MSVC,它们在默认情况下用于调试版本。对于发布版本,它们在 VC++ 2010 中默认关闭,在 VC++ 2008 和 2005 中默认开启。
      猜你喜欢
      • 1970-01-01
      • 2011-05-27
      • 2012-10-25
      • 2021-11-07
      • 1970-01-01
      • 2015-06-24
      • 2011-05-27
      • 2014-01-22
      相关资源
      最近更新 更多