当 QList 索引越界时捕获错误

Far*_*hat 0 c++ cascade blackberry-10

我正在为 Blackberry 10 开发一个应用程序,当我尝试从 QStringList 获取元素 2 而该列表仅包含 1 个元素时,我的应用程序崩溃了。

我正在使用以下代码来捕获此类错误:

try {
    //a code that accesses QStringList with an index out of bounds
}
catch (Exception e) {

}
Run Code Online (Sandbox Code Playgroud)

但异常没有被捕获,应用程序总是崩溃。

我尝试了 catch (std:exception& e) 和 catch(...) 也没有工作。

如何使用 try catch 捕获此错误?

lee*_*mes 6

访问QList超出其范围的a不会引发异常。相反,它假设您已经检查了索引是否在范围内(如果不正确会发生什么,下面将解释)。

实际上,这不是一个糟糕的设计,而是容器类的一个很好的设计:有时(在大多数情况下)您已经知道索引在范围内。如果 Qt 应该通过抛出异常来响应越界访问,这意味着您想要依赖此检查,这意味着必须完成此检查(即使您不需要 Qt 来检查它)。Qt 所做的是假设您提供了有效的索引。在调试版本中,会使用断言进行检查,如果不满足断言,则程序会因某种原因而终止(您可以很好地跟踪它以进行调试),但在发布模式下,根本不会进行此检查,因此它会默默地进行如果索引超出范围但访问数据结构中的原始内存,则会产生未定义的行为。这是尽可能快的,但要求索引有效。

如果不满足断言,断言将终止您的进程,这意味着您无法“捕获”此类错误。首先要避免它,即在访问列表之前测试索引是否在范围内。

请注意,一些(也许是全部?)容器类还提供带有“真实”索引检查的访问(不会崩溃,也在发布版本中),即在超出范围时具有定义的和预期的行为。对于QList,该函数为:

T value(int index, T fallbackValue)
Run Code Online (Sandbox Code Playgroud)

index它尝试通过边界检查访问位于的元素。如果您的索引不在范围内(或在关联容器中:未找到),fallbackValue则将返回您给出的索引。第二个参数默认为默认构造的T。请注意,即使您的索引正确,也必须构造该值。这就是为什么即使在您想要检查的情况下,最好使用分支手动进行检查,并且仅在需要时构造默认值(特别是如果您需要评估昂贵的表达式来构造后备值):

if (index < myList.count())   // We only check upper bound in this scenario
    foo = myList[index];
else
    foo = expensiveFunctionReturningMyFallbackValue();
Run Code Online (Sandbox Code Playgroud)

  • @BoBTFish 调试版本:`assert`,发布版本:“假设” (2认同)