• <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>

            printf都做了什么??

            最近在看以前的一些代碼,發(fā)現(xiàn)程序中有一些函數(shù)返回指針,而且所返回的指針是stack指針,覺(jué)得很是奇怪,stack指針都是系統(tǒng)自己維護(hù),出了作用域以后自動(dòng)釋放的,難道函數(shù)所返回的stack指針還能繼續(xù)使用?以前的代碼就是那樣,而且運(yùn)行也一直很正常,這是什么原因?覺(jué)得很是怪異。
            為測(cè)試stack指針是否由系統(tǒng)管理,從函數(shù)中返回后是否繼續(xù)可用,寫了一些代碼:
            // TestPointer.cpp : Defines the entry point for the console application.
            //
            #include "stdafx.h"
            #include 
            <windows.h>
            #include 
            <stdlib.h>

            typedef 
            struct Person
            {
                
            int iAge;
                
            int iWeight;
            }
            Person;

            //Printf都做了什么?
            //感覺(jué)調(diào)用printf時(shí)系統(tǒng)對(duì)stack進(jìn)行了清理
            char * GetString(void);
            Person 
            * GetPerson();

            int main(int argc, char* argv[])
            {
                printf(
            "Hello World!\n");

                
            char * pStr = GetString();

                
            //感覺(jué)調(diào)用printf時(shí)系統(tǒng)對(duì)stack進(jìn)行了清理
                printf("%s", pStr); //將這一句去掉后運(yùn)行試試?

                Person 
            * m_pPersion = GetPerson();
                
                printf(
            "doooooo\n"); //將這一句去掉運(yùn)行試試?
                printf("Age = %d, Weight = %d\n", m_pPersion->iAge, m_pPersion->iWeight);

                
            return 0;
            }


            char * GetString(void)
            {
                
            //簡(jiǎn)單的可以理解為: 
                
            //heap:是由malloc之類函數(shù)分配的空間所在地。地址是由低向高增長(zhǎng)的。 
                
            //stack:是自動(dòng)分配變量,以及函數(shù)調(diào)用的時(shí)候所使用的一些空間。地址是由高向低減少的。
                
            //棧(stack)內(nèi)存的情況
                char szMessage[100];
                strcpy(szMessage, 
            "this is just a test!\n");
                printf(
            "%s", szMessage);
                
            return szMessage;

                
            //堆(heap)內(nèi)存的情況
                /*char * pRet = (char *)malloc( 100 * sizeof(char));
                strcpy(pRet, "This is just a test!\n");
                return pRet;
            */
                
            }


            Person 
            * GetPerson()
            {
                
            //stack
                Person m_Person;
                m_Person.iAge 
            = 24;
                m_Person.iWeight 
            = 55;

                
            return &m_Person;

                
            //更換成heap形式的又是怎樣?
            }


            上述程序運(yùn)行環(huán)境為:WindowsXP sp2 
            + Visual C++ Enterprise Edition 6.0 + Vs6Sp6
            源代碼

            posted on 2008-04-18 20:32 猶志 閱讀(1743) 評(píng)論(5)  編輯 收藏 引用

            評(píng)論

            # re: printf都做了什么??[未登錄](méi) 2008-04-18 21:16 steven

            昏。在棧上的數(shù)據(jù)嘛,肯定沒(méi)有問(wèn)題了。  回復(fù)  更多評(píng)論   

            # re: printf都做了什么?? 2008-04-18 22:52 lonkil

            你到Release下看看.再用GCC編譯一下試試.

            我試了這幾種情況運(yùn)行結(jié)果都不一樣.

            說(shuō)明這種用法存在問(wèn)題,與printf無(wú)關(guān).

            應(yīng)該heap或在調(diào)用函數(shù)里把空間分配好,傳給子函數(shù)賦值.  回復(fù)  更多評(píng)論   

            # re: printf都做了什么?? 2008-04-19 01:01 嘯天豬

            所謂stack自動(dòng)清理的意思是:函數(shù)調(diào)用前后調(diào)整棧指針(SP)的任務(wù)編譯器會(huì)自動(dòng)幫你完成

            至于指向棧中位置的指針,當(dāng)然可以隨便用,不過(guò)這和把指針指向內(nèi)存位置0一樣,后果自負(fù)

            程序的運(yùn)行結(jié)果無(wú)法證明程序的正確性  回復(fù)  更多評(píng)論   

            # re: printf都做了什么?? 2008-04-19 22:03 starofrainnight

            這是初學(xué)者很容易犯錯(cuò)誤,想當(dāng)年我初學(xué)C++時(shí)也是對(duì)這個(gè)問(wèn)題覺(jué)得很奇怪。

            首先,把棧指針傳遞出來(lái)是原則性錯(cuò)誤,在C++裡是不允許的,而在函數(shù)結(jié)束後讀取該指針指向的內(nèi)容的行為是未知的。
            其次,棧內(nèi)存是在函數(shù)開(kāi)始執(zhí)行時(shí)進(jìn)行分配,在函數(shù)結(jié)束進(jìn)行釋放的。
            再次,棧內(nèi)容在函數(shù)結(jié)束是不會(huì)被清理的,因?yàn)獒尫帕说膬?nèi)存不需要再去清理。

            但正因?yàn)闆](méi)有進(jìn)行清理,在調(diào)用此函數(shù)後,你馬上讀取該內(nèi)存,在大部分情況下是可以讀取到原來(lái)的內(nèi)容的,只要沒(méi)有其它的程序使用到該塊內(nèi)存,那些內(nèi)容是不會(huì)改變的,但這種操作是錯(cuò)誤的,因?yàn)樵搲K內(nèi)存已經(jīng)被釋放了,你所讀取的是已經(jīng)被釋放了的內(nèi)存的內(nèi)容。

            根據(jù)各種編譯器的編譯結(jié)果不同,根據(jù)系統(tǒng)需要不同,根據(jù)你程序編寫的不同,你這個(gè)函數(shù)所產(chǎn)生的結(jié)果是不可預(yù)料的,如上,後果自負(fù)。  回復(fù)  更多評(píng)論   

            # re: printf都做了什么??[未登錄](méi) 2008-05-01 18:51 lynn

            starofrainnight說(shuō)的很對(duì);正如樓主所述,stack使用是由高向低進(jìn)行的。而您代碼中描述的:
            char szMessage[100];
            strcpy(szMessage, "this is just a test!\n");
            數(shù)組Message是如此之大,而使用卻如此之小,僅"this is just a test!\n"幾個(gè)字符。這樣,存儲(chǔ)szMessage時(shí)從低址向高址進(jìn)行,100-22=78個(gè)字節(jié)尚未使用,退出GetString函數(shù)之后。sp指針復(fù)原至調(diào)用GetString之前的位置。而調(diào)用GetPerson的活動(dòng)記錄太小,以至于沒(méi)有破壞szMessage中存儲(chǔ)的22個(gè)字符。所以,...
              回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            導(dǎo)航

            <2025年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            統(tǒng)計(jì)

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            一本久久a久久精品vr综合| 久久福利青草精品资源站免费| 久久综合狠狠综合久久97色| 久久国产香蕉一区精品| 囯产精品久久久久久久久蜜桃| 久久久久亚洲AV无码永不| 久久天天躁狠狠躁夜夜2020| 97久久精品人妻人人搡人人玩| 久久精品亚洲乱码伦伦中文| 精品乱码久久久久久久| 香蕉久久永久视频| 777久久精品一区二区三区无码 | 伊人久久大香线蕉av不卡| 狠狠干狠狠久久| 久久亚洲精品中文字幕| 婷婷久久综合| 国产一区二区精品久久凹凸| 国产午夜福利精品久久2021| 欧美日韩精品久久久免费观看| 精品久久久久久久中文字幕| aaa级精品久久久国产片| 亚洲精品高清国产一线久久| 久久久精品日本一区二区三区| 国产精品无码久久久久久| 777午夜精品久久av蜜臀| 精品伊人久久久| 一本久久免费视频| 久久夜色精品国产噜噜亚洲a| 久久亚洲国产成人影院网站| 国产综合免费精品久久久| 99久久精品久久久久久清纯| 欧美伊香蕉久久综合类网站| 久久不射电影网| 亚洲天堂久久精品| 激情五月综合综合久久69| 国内精品久久久久久不卡影院| 91精品国产高清久久久久久国产嫩草 | 久久福利资源国产精品999| 日日狠狠久久偷偷色综合96蜜桃| 久久成人永久免费播放| 少妇久久久久久被弄到高潮 |