std::out_of_range異常


使用C++容器類訪問成員時由於使用問題可能會遇到"terminate called after throwing an instance of 'std::out_of_range'"或者"Abort message: 'terminating with uncaught exception of type std::out_of_range"。問題的大概意思是:訪問越界了。沒有捕獲std::out_of_range類型的異常終止。

通常在使用vector、map這樣的C++容器類型時會遇到,這里我們以map類型為例,加以說明。

std::out_of_range異常的描述

假設我們定義了一個map類型的變量g_mapIsDestroyedRefCount,要訪問容器中的數據項有多種方式。例如,獲取g_mapIsDestroyedRefCount中key值為cameraId的值,可以這樣:

  1. g_mapIsDestroyedRefCount[cameraId]
  2. g_mapIsDestroyedRefCount.at(cameraId)

兩種寫法都可以獲取key為cameraId的value,一般效果看不出來差別,但是當g_mapIsDestroyedRefCount中不存在key為cameraId的<key, value>時就會出現“std::out_of_range”訪問越界問題。

那么疑問來了:為什么at方式訪問存在訪問越界問題,[]方式訪問不存在越界問題?因為C++容器類實現有關。

當[]方式訪問不存在的<key, value>時為什么不會std::out_of_range

[]方式訪問map容器元素時,遍歷容器元素沒找到指定的鍵值對時會將相應的鍵值對插入,鍵為檢索的key,value為零值。例如,下面例子中cameraId:2不在map中,這時通過[]式訪問,會自動將<2, 0>插入到

g_mapIsDestroyedRefCount,然后返回[2]。

導致std::out_of_range的原因

容器類型訪問方法使用有問題

對於std::map::at官方聲明:

  mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;
對於std::map::at使用有如下說明:
Access element        訪問元素

Returns a reference to the mapped value of the element identified with key k.      返回元素鍵為k的映射值的引用,即Key為k的元素的對應value值。
If k does not match the key of any element in the container, the function throws an out_of_range exception.   如果容器中沒有匹配的k鍵,該函數將拋出一個out_of_range異常

如何避免std::out_of_range異常

  • 正確使用
  • 錯誤使用

1.std::map::at的正確使用

 

#include <iostream>
#include <string>
#include <map>

std::map<int, int> g_mapIsDestroyedRefCount;

int main()
{
    int cameraId = 1;
    cout << "Let's try"<< endl;
    
     //向map中添加測試數據 
    g_mapIsDestroyedRefCount.insert(std::pair<int, int>(0, 2))'
    cout << "cameraId:"<< cameraId<< "count:";
    try {
        cout<< g_mapIsDestroyedRefCount.at(cameraId) <<endl;
    } catch (const std::out_of_range& oor) {
        std::cerr << "\nOut of range error:" << oor.what()<< endl;
    }
    cout << "try done"<< endl;
    return 0;
}

 

運行結果:

 

2.std::map::at錯誤使用

#include <iostream>
#include <string>
#include <map>
using namespace std;

std::map<int, int> g_mapIsDestroyedRefCount;

int main()
{
    int cameraId = 2;
   
   cout<< "Let's try"<< endl;
  g_mapIsDestroyedRefCount.insert(std::pair<int, int>(0, 2));
  cout<< "cameraId:"<< cameraId<< "count:";
 
  //介紹中說的方法一,可以訪問
  cout<< g_mapIsDestroyedRefCount[cameraId]<< endl;
//方法二,異常
cameraId = 2; count
<< g_mapIsDestroyedRefCount.at(cameraId)<< endl;
cout<< "try done"<< endl;
}

運行結果:(程序異常退出)

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM