简体   繁体   English

为什么我的 out_of_range 异常没有被捕获

[英]Why is my out_of_range exception not being caught

I am new to cpp and I am trying out several things.我是 cpp 的新手,我正在尝试几件事。 This one I can't seem to figure out on my own.这个我自己好像也搞不明白。

#include <cstdio>
#include <stdexcept>

template <class E, class V> 
struct Pair {
    E first;
    V second;

    Pair(E fst, V snd) : first(fst), second(snd) {}

    E getFirst() { return first; }
    V getSecond() { return second; }
};

template <class t, unsigned dim> 
struct vec {
    t d[dim];

    static constexpr int dimen = dim;

    t &operator[](unsigned n) {
        std::printf("dim: %d %d\n", dim, n);
        if (n >= dim) {
            std::printf("checking %d\n", n);
            throw std::out_of_range("vector index is out of range");
        }
        return d[n];
   };
};

int main() {

    try {
        Pair<int, vec<int, 2> *> test2(2, new vec<int, 2>{1, 2});
        std::printf("%d\n", test2.getSecond()->dimen);
        std::printf("before\n");
        std::printf("%d\n", test2.getSecond()->d[2]); // it seems like the compiler kind of ignores this
    } catch (std::out_of_range e) {
        std::printf("Caught!!");
    }
    return 0;
}

Now, the line std::printf("%d\n", test2.getSecond()->d[2]);现在,行std::printf("%d\n", test2.getSecond()->d[2]); should ideally throw the out_of_range error, but it is not.理想情况下应该抛出 out_of_range 错误,但事实并非如此。 My linter actually warns me that this is out of range also.我的 linter 实际上警告我这也超出了范围。 I can compile and run the program and it returns some garbage 0 value.我可以编译并运行该程序,它会返回一些垃圾0值。

My question is: why is either the error not being thrown or the error not being caught?我的问题是:为什么错误没有被抛出错误没有被捕获? I think the error is not being thrown because checking is not printed when I run it.我认为错误没有被抛出,因为我运行它时没有打印检查

Because the throw code is never actually reached.因为实际上从未达到throw代码。

In this line here:在此行中:

std::printf("%d\n", test2.getSecond()->d[2]);

getSection() returns a pointer to the vec object. getSection()返回指向vec object 的指针。 When you then do ->d you are accessing the d array, within the vec object.然后,当您执行->d时,您正在访问vec object 中的d数组。 Thus, when you add the [2] to the end, you are accessing the element at index 2 of the array, and are not calling operator[] of the vec object.因此,当您将[2]添加到末尾时,您正在访问数组索引 2 处的元素,而不是调用vec object 的operator[]

If you rewrite like this:如果你这样重写:

std::printf("%d\n", (*test2.getSecond())[2]);

Then the operator[] will be called on the vec object, and not its array.然后将在vec object 上调用operator[] ,而不是它的数组。 Note that you have to dereference the result of getSecond() .请注意,您必须取消引用getSecond()的结果。 Alternatively, you can be more verbose:或者,您可以更详细:

std::printf("%d\n", test2.getSecond()->operator[](2));

Working example: https://godbolt.org/z/YWKzPz工作示例: https://godbolt.org/z/YWKzPz

Very good question!非常好的问题!

The issue is that when you try to reference an item in an array via index, such as [2], you are actually referring to the size * 2 location.问题是当您尝试通过索引引用数组中的项目时,例如 [2],您实际上是在引用 size * 2 位置。 There is no built-in protection against it, but you can always check for \0 as that's where your arrays end.没有针对它的内置保护,但您始终可以检查 \0 因为这是您的 arrays 结束的地方。 When you use arrays in C/C++, it is your job to make sure you are not outside of their location.当您在 C/C++ 中使用 arrays 时,您的工作是确保您不在他们的位置之外。 It's generally a good idea to keep your array inside your structure/class and allow reaching its elements with setters and getters, which would handle the bounds and throw exceptions if those are violated.将数组保留在结构/类中并允许使用 setter 和 getter 访问其元素通常是一个好主意,这将处理边界并在违反这些边界时抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM