成人AV在线无码|婷婷五月激情色,|伊人加勒比二三四区|国产一区激情都市|亚洲AV无码电影|日av韩av无码|天堂在线亚洲Av|无码一区二区影院|成人无码毛片AV|超碰在线看中文字幕

微信加好友出現(xiàn)invalidargument strcpy函數(shù)怎么用?

strcpy函數(shù)怎么用?首先,使用步驟如下1.頭文件:#include ltstring.hgt和# includelstdio.hgt。2.功能:將從src地址開始并包含空終止符的字符串復(fù)制到從de

strcpy函數(shù)怎么用?

首先,使用步驟如下

1.頭文件:#include ltstring.hgt和# includelstdio.hgt。

2.功能:將從src地址開始并包含空終止符的字符串復(fù)制到從dest開始的地址空間。

3.描述:src和dest指示的內(nèi)存區(qū)域不能重疊,dest必須有足夠的空間來(lái)容納src字符串。返回一個(gè)指向目標(biāo)的指針。

第二,拓展

//C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)strcpy的典型工業(yè)最簡(jiǎn)單實(shí)現(xiàn)。

//返回值:目標(biāo)字符串的地址。

//參數(shù):des是目標(biāo)字符串,source是原始字符串。

char* strcpy(char* des,const char* source) {

char* rdes

斷言((des!NULL) ampamp(來(lái)源!NULL))

while((*r *source)!#390#39)

返回des

}

//while((* des * source))的解釋:賦值表達(dá)式返回左操作數(shù),所以在賦值#390#39之后,循環(huán)停止。

例如:

char a[10],b[]{#34COPY#34}

//定義字符數(shù)組a,b

strcpy(a,b)

//將副本從B復(fù)制到a。

Strcpy函數(shù)中的緩沖區(qū)溢出及其防范

C語(yǔ)言和C語(yǔ)言以其輕松靈活的風(fēng)格和寬松的語(yǔ)法限制,受到各類程序員的歡迎。它們是比較常見的編程語(yǔ)言,也是各大高校計(jì)算機(jī)專業(yè)的基礎(chǔ)語(yǔ)言課程。Strcpy函數(shù)由于不檢查數(shù)組邊界,非常容易造成各種緩沖區(qū)溢出漏洞。這些漏洞很容易被利用,導(dǎo)致嚴(yán)重的系統(tǒng)問(wèn)題。使用strcpy函數(shù)時(shí)要小心。Strcpy函數(shù)中的緩沖區(qū)溢出及其預(yù)防措施將在下面討論。[1]

緩沖區(qū)溢出問(wèn)題

緩沖區(qū)溢出是指程序在動(dòng)態(tài)分配的緩沖區(qū)中寫入了過(guò)多的數(shù)據(jù),使得分配的區(qū)域溢出。一旦一個(gè)緩沖區(qū)可以通過(guò)使用程序把運(yùn)行指令放到root權(quán)限的內(nèi)存中,并運(yùn)行這些指令,就可以用root權(quán)限控制計(jì)算機(jī)了。[1]

Strcpy函數(shù)的安全編碼

編程時(shí),通過(guò)增加錯(cuò)誤檢查,可以及時(shí)發(fā)現(xiàn)錯(cuò)誤,處理出現(xiàn)的異常。寫strcpy函數(shù)時(shí),先把目的緩沖區(qū)的長(zhǎng)度做得盡可能長(zhǎng),然后檢查目的緩沖區(qū)和源緩沖區(qū)。如果目標(biāo)緩沖區(qū)或源緩沖區(qū)為空,程序?qū)⒃诋惓L幚碇薪Y(jié)束。如果源字符串不長(zhǎng)于目標(biāo)緩沖區(qū)長(zhǎng)度。龍,也要在異常處理中結(jié)束程序,以防止溢出。任何程序都很難說(shuō)是絕對(duì)安全的,strcpy函數(shù)只能以最安全的處理。只要輸入字符串不以空字符結(jié)尾,該函數(shù)將隨時(shí)終止。這種檢測(cè)很容易實(shí)現(xiàn)。然而,這種檢測(cè)并不能確保該功能一定是安全的。[1]

另外,每增加一個(gè)錯(cuò)誤檢查,都會(huì)讓程序更加復(fù)雜,可能會(huì)產(chǎn)生很多bug,增加很多工作量。最重要的是,即使程序設(shè)計(jì)得非常仔細(xì),也可能會(huì)忽略一些細(xì)節(jié),導(dǎo)致不可挽回的錯(cuò)誤。所以寫程序的時(shí)候,最保險(xiǎn)的辦法就是盡量不要用strcpy函數(shù)。可以在程序開頭添加#define strcpy Unsafe_strcpy。這樣strcpy函數(shù)在編譯時(shí)就會(huì)產(chǎn)生錯(cuò)誤,這樣我們?cè)诰幊虝r(shí)就可以完全拋棄strcpy函數(shù)了。當(dāng)strcpy函數(shù)被完全拋棄后,很多依附于strcpy函數(shù)的bug也被拋棄。[1]

特殊情況描述

已知strcpy函數(shù)的原型是:

char * strcpy(char * strDest,const char * strSrc)

1.不調(diào)用庫(kù)函數(shù)實(shí)現(xiàn)strcpy函數(shù)。

2.解釋為什么要返回char *。

不調(diào)用庫(kù)函數(shù)如何實(shí)現(xiàn)strcpy函數(shù)

strcpy的實(shí)現(xiàn)代碼

char * strcpy(char * strDest,const char * strSrc){

if((NULLstrDest)| |(nullstrrc))

//[1]

拋出#34無(wú)效參數(shù)# 34

//[2]

char * strDestCopy strDest

//[3]

while ((*strDest *strSrc)!#390#39)

//[4]

返回strDestCopy

}

錯(cuò)誤做法[1]:

(a)不檢查指針的有效性意味著回答者不注意代碼的健壯性。

使用((!strDest)||(!StrSrc))或(!(strDestampampstrSrc)),說(shuō)明回答者對(duì)C語(yǔ)言中類型的隱式轉(zhuǎn)換沒有深刻的理解。在這種情況下,從char *到bool的轉(zhuǎn)換是隱式類型轉(zhuǎn)換。這個(gè)功能雖然靈活,但是會(huì)導(dǎo)致出錯(cuò)概率更大,維護(hù)成本更高。所以C特別添加了bool,true和false關(guān)鍵字,提供了一個(gè)更安全的條件表達(dá)式。

(c)當(dāng)檢查指針的有效性時(shí),使使用((strdest 0)| |(str rc0))說(shuō)明回答者不知道使用常數(shù)的好處。直接使用文字常量(比如本例中的0)會(huì)降低程序的可維護(hù)性。雖然0很簡(jiǎn)單,但是程序中可能會(huì)有很多對(duì)指針的檢查。萬(wàn)一出現(xiàn)筆誤,編譯器可以 t找不到,生成的程序包含邏輯錯(cuò)誤,很難消除。用NULL代替0,如果有拼寫錯(cuò)誤,編譯器會(huì)檢查出來(lái)。

錯(cuò)誤的[2]:

(A)返回新字符串(#34無(wú)效參數(shù)# 34);說(shuō)明回答者對(duì)返回值的用途沒有概念,對(duì)內(nèi)存泄漏沒有警覺。從函數(shù)中返回分配在函數(shù)體中的內(nèi)存是非常危險(xiǎn)的。他把釋放記憶的義務(wù)扔給了毫無(wú)戒心的呼叫者。在大多數(shù)情況下,調(diào)用者不會(huì)釋放內(nèi)存,從而導(dǎo)致內(nèi)存泄漏。

(B)返回0;,說(shuō)明回答者沒有掌握異常機(jī)制。調(diào)用者可能忘記檢查返回值,調(diào)用者可能無(wú)法檢查返回值(見下面的鏈?zhǔn)奖磉_(dá)式)。如果想讓返回值肩負(fù)起返回正確值和異常值的雙重功能,結(jié)果往往是兩個(gè)功能都無(wú)效。返回值應(yīng)該用拋出異常來(lái)代替,這樣可以減輕調(diào)用者的負(fù)擔(dān),使錯(cuò)誤不被忽略,增強(qiáng)程序的可維護(hù)性。

錯(cuò)誤的[3]:

(一)忘記保存原始strDest值,說(shuō)明回答者邏輯思維不嚴(yán)謹(jǐn)。

錯(cuò)誤的[4]:

(a)將循環(huán)寫成while(* strtest copy * str src);,同[1](B)。

(b)循環(huán)被寫成while(* str RC!# 390 # 39)* str dest * str src;,表明被告 對(duì)邊界條件的檢查是薄弱的。在循環(huán)體結(jié)束后,strDest字符串的末尾沒有正確添加#390#39。

解釋為什么要返回char *

返回strDest的初始值使函數(shù)能夠支持鏈表達(dá)式,這增加了 "附加值和利潤(rùn)的函數(shù)。功能相同的功能,如果可用性能得到合理提升,自然更理想。

鏈表達(dá)式的形式如下:

int iLengthstrlen(strcpy(strA,strB))

另一個(gè)例子是:

char * strAstrcpy(新char[10],strB)

返回strSrc的原始值是錯(cuò)誤的。第一,源字符串必須是已知的,返回沒有意義。第二,不能支持第二個(gè)例子那樣的表達(dá)式。第三,為了保護(hù)源字符串,形參使用const限制strSrc引用的內(nèi)容,返回const char *作為char *。類型不匹配,編譯器報(bào)告錯(cuò)誤。

在上面的語(yǔ)句中,循環(huán)語(yǔ)句

while ((*strDestCopy *strSrc)!#390#39)

很難理解,這句話可以理解為下面的操作。

第一種:

while( 1 ){

炭化溫度

*strDestCopy *strSrc

溫度* strSrc

strDestCopy

strSrc

如果(#390#39溫度)

破裂

}

第二種類型:

while(* strrc!#390#39 ){

*strDestCopy *strSrc

strDestCopy

strSrc

}

*strDestCopy *strSrc

即:

while(* strrc!#390#39 ){

*strDestCopy *strSrc

}

* strDestCopy“0”

使用示例

//例1:將一個(gè)字符串復(fù)制到一個(gè)足夠長(zhǎng)的字符數(shù)組中。在本例中,字符數(shù)組是一個(gè),長(zhǎng)度為20。

//缺點(diǎn):如果數(shù)組長(zhǎng)度不足以容納整個(gè)字符串,程序會(huì)崩潰。

#includeltiostreamgt

#includeltstdlib.hgt

使用命名空間標(biāo)準(zhǔn)

char * strcpy( char * strDest,const char * strSrc ){

char * strDestCopy strDest

if((NULLstrDest)| |(nullstrrc))拋出#34無(wú)效參數(shù)# 34

while ( (*strDest *strSrc)!#390#39 )

返回strDestCopy

}

int main( int argc,char * argv[] ){

char a[20],c[]# 34我是老師!#34

嘗試{

strcpy(a,c)

}catch(char* strInfo){

cout ltlt strInfo ltlt endl

退出(-1)

}

cout ltlt a ltlt endl

返回0

}

//例2:預(yù)置了兩個(gè)字符指針,一個(gè)指向字符串,一個(gè)指向NULL,在程序運(yùn)行過(guò)程中復(fù)制。

#includeltiostreamgt

使用命名空間標(biāo)準(zhǔn)

char *strcpy(char *strDes,const char *strSrc)

//函數(shù)聲明

int main(){

const char * strrc # 34 hello world # 34

char *strDesNULL

strDesstrcpy(strDes,strSrc)

cout ltlt # 34 strsrc # 34 ltlstrsrcltltendl

coultlt # 34 strdes # 34 ltltstrdestltendl

如果(strDes!NULL) {

免費(fèi)(strDes)

strDesNULL

}

返回0

}

char *strcpy(char *strDes,const char *strSrc){

斷言(strSrc!空)

//如果strSrc為NULL,則引發(fā)異常。

strDes(char *)malloc(strlen(str src)1)

//多一個(gè)空間用于存儲(chǔ)字符串終止符#390#39。

char *pstrDes

while(* strrc!#390#39){

* p * strSrc

}

*p#390#39

返回strDes

}

還有一個(gè)模擬算法:

char * strcpy(char *dest,const char *src){

char *pdest

while (*src!#390#39){

*dest *src

目標(biāo)服務(wù)中心

}

*目的地#390#39

返回p

}

與strncpy的區(qū)別

第一種情況:

你好嗎?#34

char name[20]# 34 abcdefghijklmnopqrs # 34

strcpy(名稱,p)

//名字改成# 34你好嗎?#34gt正確!

strncpy(name,p,sizeof(name))

//名字改成# 34你好嗎?#34 gt正確!后續(xù)字符將為空。

第二種情況:

你好嗎?#34

字符名稱[10]

strcpy(名稱,p)

//目標(biāo)字符串的長(zhǎng)度小于源字符串的長(zhǎng)度,錯(cuò)誤!

名稱[sizeof(name)-1]

//而上一步,彌補(bǔ)了結(jié)果,但這是不可取的。因?yàn)樯弦徊降腻e(cuò)誤處理方法是不確定的。

strncpy(nam

keil 報(bào)錯(cuò)invalid argument?

Keil報(bào)告了invalud參數(shù),這意味著非法參數(shù),并且不支持當(dāng)前語(yǔ)法。

標(biāo)簽: