日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C++函數(shù)返回指針和引用的坑

常用C++進(jìn)行項(xiàng)目開發(fā)的童鞋們應(yīng)該都知道,在C++中指針和引用是常用的語法了,而指針又是C++區(qū)別于其他高級語言的一大精髓。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),都安企業(yè)網(wǎng)站建設(shè),都安品牌網(wǎng)站建設(shè),網(wǎng)站定制,都安網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,都安網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

而今天我們再來看看在C++新手們針對指針和引用的使用經(jīng)常犯的錯(cuò)誤。

函數(shù)返回指針

在C++中針對一個(gè)函數(shù)返回指針的實(shí)現(xiàn)方式一般有三種:

1.返回一個(gè)變量的地址

例如以下代碼:

// 返回int指針地址
int * funTest(){
    int a = 101;
    return &a;
}

int main(int argc, const char *argv[]) {
    int *a = funTest();
    std::cout << "a的值:" << *a << std::endl;
    return 0;
}

以上代碼在筆者的電腦上運(yùn)行就直接報(bào)錯(cuò)崩潰了,崩潰信息:

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

上面的代碼返回一個(gè)局部變量a的地址,這個(gè)變量a緊在函數(shù)funTest內(nèi)有效,當(dāng)函數(shù)funTest結(jié)束了,變量a的生命周期也就結(jié)束了, 此時(shí)變量a所占用的內(nèi)存空間將被釋放,因此返回的指針地址將會(huì)被指向一個(gè)未知數(shù),后續(xù)再使用這個(gè)指針是未定義的行為,可能會(huì)導(dǎo)致程序崩潰或者出現(xiàn)其他異常。

針對這樣的危險(xiǎn)代碼行為,其實(shí)編輯器也已經(jīng)給出了警告,所以說在開發(fā)過程中也不要以為的忽略警告哦。

為了杜絕此類行為的發(fā)生,還可以使用筆者之前的介紹的代碼質(zhì)量檢測工具cppcheck進(jìn)行檢測,在開發(fā)過程中直接劃線提醒。

介紹一款CPP代碼bug檢測神器。

2.返回一個(gè)使用static修飾的變量地址

我們修改一下funTest函數(shù)的變量a,使用static關(guān)鍵字修飾一下:

// 返回int指針地址
int * funTest(){
    static int a = 101;
    return &a;
}

int main(int argc, const char *argv[]) {
    int *a = funTest();
    std::cout << "a的值:" << *a << std::endl;
    return 0;
}

運(yùn)行發(fā)現(xiàn)程序并沒有崩潰,而且是正確打印出了變量a的值。這是因?yàn)?使用static 表示將這個(gè)變量存儲(chǔ)到全局區(qū)(static靜態(tài)區(qū)), 此時(shí)就不受棧區(qū)管控,當(dāng)函數(shù)funTest執(zhí)行完畢后,變量a依然存在,不會(huì)存在前面所說的變量地址被釋放的問題。

3.使用動(dòng)態(tài)分配內(nèi)存new關(guān)鍵字

int * funTest(){
    //動(dòng)態(tài)分配的內(nèi)存空間,手動(dòng)delete后才會(huì)釋放
    int* a = new int(101) ;
    return a;
}

int main(int argc, const char *argv[]) {
    int *a = funTest();
    std::cout << "a的值:" << *a << std::endl;
    return 0;
}

上述代碼不會(huì)崩潰,也能正常運(yùn)行,但是存在一個(gè)隱患就是返回的指針變量a如果忘記調(diào)用delete則會(huì)造成內(nèi)存泄露, 這就引發(fā)了一個(gè)指針變量誰維護(hù)銷毀的問題。一般默認(rèn)規(guī)則是誰開發(fā)維護(hù)。

因此,針對這樣的場景,筆者的建議是智能指針你值得擁有...

函數(shù)返回一個(gè)引用

我們看看以下返回一個(gè)引用的例子代碼:

int & funTest(){
    //動(dòng)態(tài)分配的內(nèi)存空間,手動(dòng)delete后才會(huì)釋放
    int a = 101 ;
    return a;
}

int main(int argc, const char *argv[]) {
    int a = funTest();
    std::cout << "a的值:" << a << std::endl;
    return 0;
}

筆者在CLion上測試也是直接崩潰了,原因也是和上面所說的返回一個(gè)局部變量的地址一樣, 都是因?yàn)楹瘮?shù)funTest結(jié)束后,變量a的生命周期結(jié)束了, 變量a也就是被釋放了,再返回它的引用的話就是未定義的。至于為什么它們的原因是一樣的呢?因?yàn)樗^引用,可以簡單地理解為引用其實(shí)就是帶const修飾的指針。

那么針對這個(gè)問題該如何修正呢?首先使用static關(guān)鍵字肯定是可以的。那么使用動(dòng)態(tài)內(nèi)存new的方式行不行呢?答案也是可行的,但是需要注意的一點(diǎn)就是如果一個(gè)引用 的值來源于一個(gè)指針,后來這個(gè)指針被delete掉了,那么再使用這個(gè)引用也是會(huì)造成崩潰的...

如何返回一個(gè)數(shù)組

那么問題來了,舉一反三,如果想通過一個(gè)函數(shù)返回一個(gè)數(shù)組那該如何實(shí)現(xiàn)呢?

眾所周知,C++是不允許直接返回一個(gè)數(shù)組的,如果您想要從函數(shù)返回一個(gè)一維數(shù)組,您必須聲明一個(gè)返回指針的函數(shù)。

例如下面的寫法是編譯不通過的:

// 無法編譯通過,不能返回一個(gè)數(shù)組
int[] funTest(){
    int myArray[3] = {1, 2, 3};
    return myArray;
}

正確的寫法應(yīng)該是:

int* funTest(){
    static int myArray[3] = {1, 2, 3};
    return myArray;
}

因而可以看出,其實(shí)返回一個(gè)數(shù)組的函數(shù)所遇到的坑其實(shí)就轉(zhuǎn)換成了返回一個(gè)指針的函數(shù)所遇到的坑,這些坑的舉例就如前面所說...


網(wǎng)站欄目:C++函數(shù)返回指針和引用的坑
本文URL:http://m.5511xx.com/article/coedjjp.html