## 邊界檢查
## 邊界檢查
?(2014-02-18 10:05:42)
轉載▼
| | 分類:?[C/Cpp](http://blog.sina.com.cn/s/articlelist_1198604677_2_1.html) |
邊界檢查在[程序設計](http://zh.wikipedia.org/wiki/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1 "程序設計")中是指在使用某一個[變量](http://zh.wikipedia.org/wiki/%E5%8F%98%E9%87%8F_(%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1) "變量 (程序設計)")前,用來檢查該變量是否處在一個特定范圍之內的過程。最常見的是[數組](http://zh.wikipedia.org/wiki/%E6%95%B0%E7%BB%84 "數組")的下標檢查,來防止下標超出數組的范圍而覆蓋其他的數據
由于每次都進行邊界檢查非常耗時,而且有些代碼是不可能產生越界的問題的,所以這個操作并不總是需要被執行。一些現代的[編譯器](http://zh.wikipedia.org/wiki/%E7%BC%96%E8%AF%91%E5%99%A8 "編譯器")中有被稱為選擇性邊界檢查的技術可以略去一些常見的不需要的邊界檢查來提高程序的性能。
當前的常見編程語言中,強制進行邊界檢查的有[C#](http://zh.wikipedia.org/wiki/C%E2%99%AF "C?")、[Ada](http://zh.wikipedia.org/wiki/Ada "Ada")、[Haskell](http://zh.wikipedia.org/wiki/Haskell "Haskell")、[Java](http://zh.wikipedia.org/wiki/Java "Java")、[JavaScript](http://zh.wikipedia.org/wiki/JavaScript "JavaScript")、[Lisp](http://zh.wikipedia.org/wiki/Lisp "Lisp")、[PHP](http://zh.wikipedia.org/wiki/PHP "PHP")、[Python](http://zh.wikipedia.org/wiki/Python "Python")、[Ruby](http://zh.wikipedia.org/wiki/Ruby "Ruby")和[Visual Basic](http://zh.wikipedia.org/wiki/Visual_Basic "Visual Basic")。其中C#同時也支持“unsafe塊”(不安全代碼塊),即一段暫時關閉邊界檢查、啟用指針以提高效率的代碼塊。這個功能常被用于加速一些小塊的不可能出現越界的代碼的執行,而不導致破壞整個程序的安全性。除了這些語言外,[D語言](http://zh.wikipedia.org/wiki/D%E8%AF%AD%E8%A8%80 "D語言")和[OCaml](http://zh.wikipedia.org/wiki/OCaml "OCaml")也支持自動邊界檢查,但是允許用戶通過編譯器的一個開關選項來選擇是否啟用該功能。
然而有一些[編程語言](http://zh.wikipedia.org/wiki/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80 "編程語言")(比如[C語言](http://zh.wikipedia.org/wiki/C%E8%AF%AD%E8%A8%80 "C語言"))為了提高速度,從來都不會自動進行邊界檢查,這經常導致[差一錯誤](http://zh.wikipedia.org/w/index.php?title=%E5%B7%AE%E4%B8%80%E9%94%99%E8%AF%AF&action=edit&redlink=1 "差一錯誤(頁面不存在)")(又稱“[柵欄錯誤](http://zh.wikipedia.org/w/index.php?title=%E6%A0%85%E6%A0%8F%E9%94%99%E8%AF%AF&action=edit&redlink=1 "柵欄錯誤(頁面不存在)")”:一個柵欄被一些柱子分區成10段,柱子的根數應該是*11*根,而不是*10*根。)和[緩沖區溢出](http://zh.wikipedia.org/wiki/%E7%BC%93%E5%86%B2%E5%8C%BA%E6%BA%A2%E5%87%BA "緩沖區溢出")的發生。許多程序員認為這些語言為了速度所付出的代價太大了
?
范圍檢查
范圍檢查經常被用于確保某個數字處在一個特定的范圍之內。通常在訪問[數組](http://zh.wikipedia.org/wiki/%E6%95%B0%E7%BB%84 "數組")的時候會進行該檢查,因為當數組下標越界的時候,數據會被寫入其它變量的空間,甚至會覆蓋壓棧的寄存器數值。這樣一來,程序可能會崩潰,或者是導致一些安全漏洞的產生(見[緩沖區溢出](http://zh.wikipedia.org/wiki/%E7%BC%93%E5%86%B2%E5%8C%BA%E6%BA%A2%E5%87%BA "緩沖區溢出"))。在[Java](http://zh.wikipedia.org/wiki/Java "Java")中,[Java虛擬機](http://zh.wikipedia.org/wiki/Java%E8%99%9A%E6%8B%9F%E6%9C%BA "Java虛擬機")將在嘗試訪問數組中的元素的時候,自動的進行數組邊界檢查,并且在下標越界的時候引發[異常](http://zh.wikipedia.org/wiki/%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86 "異常處理")。
范圍檢查的另一個常見用途是在兩種數據類型相互轉換的時候。在構建在[.NET Framework](http://zh.wikipedia.org/wiki/.NET_Framework ".NET Framework")上的語言中,超出范圍的強制轉換將引發InvalidCastException類型的異常。
比如將一個[32位有符號整數](http://zh.wikipedia.org/wiki/%E6%95%B4%E6%95%B0#.E9.9B.BB.E8.85.A6.E4.B8.AD.E7.9A.84.E6.95.B4.E6.95.B8 "整數")類型的變量強制轉換到一個[16位有符號整數](http://zh.wikipedia.org/wiki/%E6%95%B4%E6%95%B0#.E9.9B.BB.E8.85.A6.E4.B8.AD.E7.9A.84.E6.95.B4.E6.95.B8 "整數")類型的變量之前,會檢查這個變量的值是否在-32768~+32767?之間(16位有符號整數可以表示的整數范圍),而不是諸如32768之類的無法表示的數字。
數組下標檢查
數組下標檢查是指在程序中,所有數組下標的[表達式](http://zh.wikipedia.org/wiki/%E8%A1%A8%E8%BE%BE%E5%BC%8F "表達式")的結果在真正被用來訪問某一個特定的元素之前,先把它的值和定義[數組](http://zh.wikipedia.org/wiki/%E6%95%B0%E7%BB%84 "數組")時給出的數組上界和下界進行比較。如果一個下標超出了預期的范圍時,那么就引發一個錯誤來阻止進一步的訪問。(例如:[.NET Framework](http://zh.wikipedia.org/wiki/.NET_Framework ".NET Framework")中的IndexOutOfRangeException和ArgumentOutOfRangeException類型[異常](http://zh.wikipedia.org/wiki/%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86 "異常處理"))
比如在訪問一個下標范圍是0~9的數組前檢查下標是否也在?0~9內,而不是如25之類的越過數組結尾的下標。
除了軟件實現的下標檢查之外,[VAX](http://zh.wikipedia.org/wiki/VAX "VAX")架構的計算機擁有一條INDEX匯編指令,可以用來檢查數組的下標是否越界,可以至多提供6個任意VAX編址的地址。B6500和一些相似的[伯勒斯](http://zh.wikipedia.org/w/index.php?title=%E4%BC%AF%E5%8B%92%E6%96%AF&action=edit&redlink=1 "伯勒斯(頁面不存在)")計算機則以硬件進行邊界檢查,無論是采用什么語言撰寫的程序。
數據驗證
在數據集合數據質量范疇中,邊界檢查表示檢查一個并不總是錯誤的數據。比如,一個成年人的身高應該處在0到3米之間、利用率應該在0到1之間等。
?
?例如以下代碼:
int?main()
{
????inti[10]?=?{0};
????int?p?=?0;
????for(p=0;p10;p++)
????{
????????i[p]?=?4;
????}
????return?0;
}
當訪問i[10]的時候數組下標越界,實際上訪問了p所在的內存,于是p被設置成4繼續循環,這樣一來程序只會死循環而不會終止運行
以下行為,編譯可以通過,并且能夠運行。 1:聲明數組但不初始化。2:數組越界。
# C++指針:對于多維數組,所謂“不檢查數組邊界”只不檢查最高維(第一維)的邊界,其他邊界控制
比如說int a[5][2]實際上在內存里面是連續的10個int,分別為第0個到第9個元素, 所以??a[3][2]?(雖然越界)但實際上等于3*2+2=8,第8個元素,即a[4][0]
參考:[http://book.2cto.com/201312/38501.html](http://book.2cto.com/201312/38501.html)?C11附錄K邊界檢查接口
來源:[邊界檢查_0o青絲_新浪博客](http://blog.sina.com.cn/s/blog_477141850101g455.html)
### 擴展
[關于程序的邊界檢查 - CSDN博客](http://blog.csdn.net/lanonjj/article/details/52739874)
last update:2018-1-19 03:07:21
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 科目一
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南