簡體   English   中英

為什么我的 out_of_range 異常沒有被捕獲

[英]Why is my out_of_range exception not being caught

我是 cpp 的新手,我正在嘗試幾件事。 這個我自己好像也搞不明白。

#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;
}

現在,行std::printf("%d\n", test2.getSecond()->d[2]); 理想情況下應該拋出 out_of_range 錯誤,但事實並非如此。 我的 linter 實際上警告我這也超出了范圍。 我可以編譯並運行該程序,它會返回一些垃圾0值。

我的問題是:為什么錯誤沒有被拋出錯誤沒有被捕獲? 我認為錯誤沒有被拋出,因為我運行它時沒有打印檢查

因為實際上從未達到throw代碼。

在此行中:

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

getSection()返回指向vec object 的指針。 然后,當您執行->d時,您正在訪問vec object 中的d數組。 因此,當您將[2]添加到末尾時,您正在訪問數組索引 2 處的元素,而不是調用vec object 的operator[]

如果你這樣重寫:

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

然后將在vec object 上調用operator[] ,而不是它的數組。 請注意,您必須取消引用getSecond()的結果。 或者,您可以更詳細:

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

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

非常好的問題!

問題是當您嘗試通過索引引用數組中的項目時,例如 [2],您實際上是在引用 size * 2 位置。 沒有針對它的內置保護,但您始終可以檢查 \0 因為這是您的 arrays 結束的地方。 當您在 C/C++ 中使用 arrays 時,您的工作是確保您不在他們的位置之外。 將數組保留在結構/類中並允許使用 setter 和 getter 訪問其元素通常是一個好主意,這將處理邊界並在違反這些邊界時拋出異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM