您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關怎么使用span解決數組退化和越界訪問,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
數組是C++從C語言繼承過來的特性,使用方便同時又可以提供絕佳的性能,因此被廣泛使用。但是簡便的另一面就是風險,其中最大的兩個問題就是退化(array decay)和越界訪問(range errors)。本如何提前使用C++20新特性span解決數組退化和越界訪問的問題。
首先看使用數組的最常見代碼:
int data[10];for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) { data[i] = 0;}
數組被定義時,同時有個元素個數信息。使用這個信息可以對數組進行操作。但是在將數組作為一個參數傳遞給某個函數時,只能以指針形式傳遞,這就是數組退化。為了正確把握數組的大小一般需要同時傳遞數組的大小信息。例如下面的初始化函數就是如此:
void init_data(int buffer[], size_t size){ cout << "size=" << size << endl; for (gsl::index i = 0; i < size; ++i) { buffer[i] = i; } buffer[4] = 40; buffer[20] = 20; //越界訪問}
即使聲明函數參數時形式上是數組,但所有的行為都和指針完全相同。還有一個問題就是,由于數組是一種完全暴露的數據結構,沒有任何保護。例如代碼中第8行,即使訪問的第20個元素已經超過最初定義的10個元素,這種操作一般也會正常通過。但是接下來不知道哪個時刻,這個操作帶來的影響就會以一種完全不相關的形式表現出來。數組大小信息獲取,傳遞錯誤和越界操作具有引入容易、排查困難的特種,是許多程序員的噩夢。
為了解決這個問題,GSL引入了一個模板類span,它可以同時管理數組的地址和大小。這個類將從C++20開始成為C++的標準功能。
使用了span類的初始化函數如下:
void init_data(gsl::span<int> buffer){ cout << "size=" << buffer.size() << endl; int value = 0; for (auto it = buffer.begin(); it != buffer.end(); it++) { *it = value++; } buffer[4] = 10; buffer[20] = 20; //會觸發斷言}
只要函數參數聲明為:gsl::span<int> buffer,大小信息就會由span模板類管理,接下來就可以像vector一樣使用數組了。如果發生越界訪問,會觸發斷言。
使用數組和span傳遞參數的示例代碼如下:
int main(){ int data[10]; for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) { data[i] = 0; } //使用數組傳遞參數 init_data(data, 5); //使用span傳遞參數 init_data(data); return 0;}
和使用數組的調用相比,增強功能(范圍檢查等)的同時還簡化了數組的用法!
以上就是怎么使用span解決數組退化和越界訪問,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。