官术网_书友最值得收藏!

2.5.9 strlen()

strlen()函數沒有特別的缺陷,但由于底層字符串表示的弱點,它的操作可能被破壞。strlen()函數接受一個指向一個字符數組的指針,并返回終止空字符之前的字符數量。如果字符數組不是正確地以空字符結尾的,strlen()函數可能會返回一個錯誤的超大的數值,使用它時,就可能會導致漏洞。此外,如果傳入一個非以空字符結尾的字符串,strlen()函數可以越過動態分配的數組的邊界讀取,并導致程序停止運行。

C99。C99沒有定義strlen()的替代函數。因此,在開發嚴格符合C99的程序時,在將字符串傳遞給strlen()函數之前,有必要確保它們是正確地以空值結尾的,從而使函數的結果在預期范圍內。

C11附錄K邊界檢查接口。C11提供了一種替代strlen()的函數—帶邊界檢查的strnlen_s()函數。另外,對于一個字符指針,strnlen_s()函數接受一個最大大小。如果字符串的長度超過指定的最大大小,那么返回最大大小,而不是字符串的實際長度。strnlen_s()函數沒有運行時約束。這種運行時約束的缺乏,以及以一個空指針或一個未終止字符串參數返回的值,使得strnlen_s()在優雅地處理這些異常數據的算法中非常有用。

有一種誤解,認為帶邊界檢查的函數總是天生就比相應的傳統函數更安全且傳統的函數不應該被使用。教條地把對C99函數的調用替換為對帶邊界檢查的函數的調用,這會導致令人費解的代碼,而不比使用傳統的函數更安全,并且效率低下,難以閱讀。例如,要獲得一個字符串字面值的長度,教條地使用帶邊界檢查的函數會導致下面這樣的愚蠢代碼。


#define S "foo" 
size_t n = strnlen_s(S, sizeof S); 

在處理可能缺乏結尾的空字符的字符串時,strnlen_s()函數很有用。該函數返回不含空終止字符的數組中的元素的數量,致使許多計算更直接。

因為C11附錄K中定義的帶邊界檢查的函數,不產生不帶結束符的字符串,所以在大多數情況下,把對strlen()函數的調用替換為對strnlen_s()的調用是不必要的。

strnlen_s()函數與POSIX的函數strnlen()是相同的。

主站蜘蛛池模板: 宁都县| 修水县| 诸暨市| 军事| 兴国县| 崇阳县| 霞浦县| 桂平市| 桐乡市| 曲靖市| 海原县| 磐安县| 黄山市| 乳山市| 普定县| 合川市| 正阳县| 峡江县| 巴彦县| 姜堰市| 闸北区| 同德县| 吴桥县| 浪卡子县| 陆川县| 甘南县| 北碚区| 新沂市| 呼图壁县| 长武县| 江西省| 宾川县| 滕州市| 武川县| 科尔| 来凤县| 思茅市| 临西县| 团风县| 茶陵县| 昆明市|