• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Mike's blog

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              0 Posts :: 23 Stories :: 83 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(17)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評(píng)論

            先看一個(gè)例子:
             1#include <stdio.h>
             2#include <stdlib.h>
             3#include <string.h>
             4
             5char* fun(const char* src)
             6{
             7  static char dest[32= "";
             8  
             9  strcpy(dest, src);
            10
            11  return dest;
            12}

            13
            14int main()
            15{
            16  char s1[32= "";
            17  char s2[32= "";
            18
            19  strcpy(s1, fun("hello"));
            20  strcpy(s2, fun("world"));
            21
            22  printf("%s %s\n", s1, s2);
            23  printf("%s %s\n", fun("hello"), fun("world"));
            24
            25  return 0;
            26}

                讀一下這個(gè)程序,先看這個(gè)程序?qū)懙挠袉?wèn)題沒(méi)(假設(shè)fun函數(shù)的參數(shù)長(zhǎng)度小于32)?如果你對(duì)這個(gè)程序中的fun函數(shù)返回一個(gè)局部變量的數(shù)組產(chǎn)生了疑問(wèn),那么我希望你是沒(méi)注意到我使用的static類(lèi)型,若你仍有疑問(wèn),建議你先回去查查static變量的作用域和生命周期的概念。
                OK,是運(yùn)行這個(gè)程序的時(shí)候了,看一下運(yùn)行結(jié)果是否跟你想象的一樣呢?如果是一樣的,那么這篇文章你不用看了,因?yàn)槟阋呀?jīng)掌握了我下面要說(shuō)的問(wèn)題了。好吧,對(duì)于不理解運(yùn)行結(jié)果的朋友,我們來(lái)分析一些下面那個(gè)printf語(yǔ)句,首先要知道printf中的表達(dá)式、函數(shù)的執(zhí)行順序是至右向左的,也就是先執(zhí)行了fun("world")返回了dest的地址,然后再執(zhí)行fun("hello")也返回了dest的地址,而這兩次返回的dest用的同一塊地址(因?yàn)槭莝tatic類(lèi)型),也就是第二次的執(zhí)行覆蓋了第一次執(zhí)行的結(jié)果,對(duì)dest地址進(jìn)行了重新的賦值,所以結(jié)果就是打印兩個(gè)hello了。


                我們?cè)趯?xiě)C/C++程序的時(shí)候,經(jīng)常需要從調(diào)用函數(shù)中取得自己想要的數(shù)據(jù),這就需要調(diào)用者和函數(shù)之間要有個(gè)內(nèi)存的交互,我們通常采用的方法是傳遞一個(gè)指針給被調(diào)函數(shù),作為被調(diào)函數(shù)的輸出參數(shù),這也是我們常用的、規(guī)范的做法。
                但有很多程序員比較習(xí)慣直接取返回值,這就面臨一個(gè)問(wèn)題就是普通局部變量都是在棧上分派的,會(huì)隨著函數(shù)的結(jié)束而彈棧釋放,那么就會(huì)出現(xiàn)返回局部變量數(shù)組的問(wèn)題,這時(shí)有人會(huì)想到用malloc或new在堆上分派內(nèi)存,沒(méi)錯(cuò),這樣是避免了前面說(shuō)的問(wèn)題,但這樣又會(huì)帶來(lái)新的問(wèn)題,就是需要在外部對(duì)這塊內(nèi)存進(jìn)行釋放,這個(gè)是比較難把握的,多次釋放會(huì)出現(xiàn)程序的crash,忘記釋放了會(huì)出現(xiàn)內(nèi)存leak,所以這種方法也不被推薦。還有人想到了更另類(lèi)的方法,就是上面例子中的static類(lèi)型,沒(méi)錯(cuò),static變量也是全局的,但就會(huì)出現(xiàn)上面程序的運(yùn)行結(jié)果(可以認(rèn)為不是我們想要的結(jié)果,也就是錯(cuò)誤的結(jié)果)。
                所以,我們要慎用返回函數(shù)內(nèi)部的static內(nèi)存的這種設(shè)計(jì),但如果在無(wú)法改變?cè)O(shè)計(jì)模式的情況下(有些系統(tǒng)函數(shù)的實(shí)現(xiàn),比如inet_ntoa,可以通過(guò)在man手冊(cè)中看到這樣的一句話(huà):The string is returned in a statically allocated buffer, which subsequent calls will overwrite),那么在自己使用的時(shí)候一定要注意,不要試圖保存返回的內(nèi)存地址或引用,而要保存返回內(nèi)存的內(nèi)容,也就是例子程序中的strcpy兩行。

            inet_ntoa的錯(cuò)誤使用(判斷兩個(gè)IP地址是否相等):

             1struct in_addr addr1;
             2struct in_addr addr2;
             3
             4// 網(wǎng)絡(luò)包中包含了源地址
             5addr1.s_addr = 0x6500A8C0 // 192.168.0.101
             6addr2.s_addr = 0x6600A8C0 // 192.168.0.102
             7
             8// 這個(gè)if語(yǔ)句將永遠(yuǎn)為真
             9if (strcmp(inet_ntoa(addr1), inet_ntoa(addr2)) == 0{
            10  // do something
            11}
             else {
            12  // do other thing
            13}
            posted on 2008-11-25 15:06 老狼 閱讀(768) 評(píng)論(2)  編輯 收藏 引用 所屬分類(lèi): C/C++

            Feedback

            # re: 返回static內(nèi)部變量的陷阱[未登錄](méi) 2008-11-27 15:05 小兵
            學(xué)習(xí)了  回復(fù)  更多評(píng)論
              

            # re: 返回static內(nèi)部變量的陷阱 2009-01-07 12:18 July
            很好的文章,謝謝分享  回復(fù)  更多評(píng)論
              

            91久久福利国产成人精品| 久久九九全国免费| 久久综合国产乱子伦精品免费| 中文字幕乱码久久午夜| 潮喷大喷水系列无码久久精品| 国产精品欧美亚洲韩国日本久久| 日批日出水久久亚洲精品tv| 久久精品国产亚洲AV嫖农村妇女| 久久精品国产99国产精品| 国产成人久久精品一区二区三区| 欧美色综合久久久久久| 狠狠色婷婷综合天天久久丁香| 午夜福利91久久福利| 亚洲一区中文字幕久久| 久久亚洲熟女cc98cm| 精品熟女少妇aⅴ免费久久| 久久精品国产亚洲av水果派 | 亚洲一区中文字幕久久| 久久亚洲精品成人无码网站| 99久久国产综合精品五月天喷水| 欧洲人妻丰满av无码久久不卡| 性高湖久久久久久久久AAAAA| 91精品婷婷国产综合久久| 国产成年无码久久久久毛片| 日日噜噜夜夜狠狠久久丁香五月| 手机看片久久高清国产日韩| 国产精品99久久久久久猫咪| 久久99精品国产| 国产美女久久精品香蕉69| 色婷婷综合久久久久中文一区二区| 97久久婷婷五月综合色d啪蜜芽| 久久综合色之久久综合| 精品久久人人爽天天玩人人妻 | 国内精品九九久久精品| 怡红院日本一道日本久久| 亚洲精品高清久久| 99热成人精品免费久久| 国内精品久久久久影院网站| 久久996热精品xxxx| 久久久久18| 国产亚洲美女精品久久久2020|