深入理解strncpy这个函数
生活随笔
收集整理的這篇文章主要介紹了
深入理解strncpy这个函数
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1.不考慮內(nèi)存重疊的strncpy
網(wǎng)上很多博客也寫了這個函數(shù),面試也常常會遇到,但是,我發(fā)現(xiàn)網(wǎng)上的很多代碼都是有問題的,我們先看下大部分網(wǎng)上博客的實現(xiàn): [plain]?view plain?copy看著好像沒啥問題,但是,當src的長度小于len呢?這份代碼沒有處理這個問題。當src的長度小于len時,應(yīng)該如何處理?《C和指針》p179給出的答案是: “和strcpy一樣,strncpy把源字符串的字符復制到目標數(shù)組。然而,它總是正好向dst寫入len個字符。如果strlen(src)的值小于len,dst數(shù)組就用 額外的NUL字節(jié)填充到len長度,如果strlen(src)的值大于或等于len,那么只有l(wèi)en個字符被復制到dst中?!?/strong> 注意!它的結(jié)果將不會以NUL字節(jié)結(jié)尾。(NUL即‘\0’). 由此可見,我們還需要判斷strlen(src)是否小于len,如果是,還需要在dst后面添加NUL,因此,正確的代碼應(yīng)該如下: [plain]?view plain?copy
? 使用這個函數(shù),尤其需要注意,不要出現(xiàn)len>strlen(dst)的情況,如果len>strlen(dst),那么會破壞dst后面的內(nèi)存: 我們假設(shè)前面紅色部分是dst,然后strncpy(dst,src,10);那么后面黃色部分的內(nèi)存就被破壞了。strncpy是不負責檢測len是否大于dst長度的。 總的來說,strncpy總是復制len個字符到dst指向的內(nèi)存!!! 所以,還會出現(xiàn)下面的情況: [plain]?view plain?copy
message的內(nèi)存是有5個字節(jié)的,但是將abcde拷貝過去時,最后面的‘\0’被覆蓋了,strncpy并不會負責添加‘\0’到dst結(jié)尾,因此,輸出該字符串是,會在e字符后面一直找到‘\0’才結(jié)束,因此就會出現(xiàn)亂碼。
2.考慮內(nèi)存重疊的strncpy
面試中經(jīng)常會遇到讓你寫一個能夠處理內(nèi)存重疊的strncpy,標準庫中的strncpy是不考慮內(nèi)存重疊的,如果出現(xiàn)內(nèi)存重疊,結(jié)果將是未定義的。 網(wǎng)上的很多博客也有這個代碼的實現(xiàn),其實很多也是有問題的,沒有考慮src長度小于len的問題: [plain]?view plain?copy? 那么,如果要處理內(nèi)存重疊,該怎么辦?如果內(nèi)存重疊和src的長度小于len這兩種情況同時出現(xiàn),又如何處理? 見圖,假設(shè)紅色部分為src,黃色為dst。如果出現(xiàn)內(nèi)存重疊,我們很容易想到:從后往前拷貝。如果src的長度小于len,則在后面補NUL。 [plain]?view plain?copy
那么,如果len的值大于dst的值,就會破壞dst后面的內(nèi)存空間,這應(yīng)該是要避免的。 最后,我們看一個有意思的東西:(此處strncpy是考慮內(nèi)存重疊的版本) message的長度增加了0.0 ?當然 ?,它后面的內(nèi)存被破壞了,這可能帶來嚴重的后果。 最后,使用strncpy時,最好自動添加‘\0’在結(jié)尾: [plain]?view plain?copy
總結(jié)
以上是生活随笔為你收集整理的深入理解strncpy这个函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32用USART发送字符串,以US
- 下一篇: 现实工程中常用到的C语言函数总结(不断更