亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

基于C++內存分配、函數調用與返回值的深入分析

2020-01-26 16:04:58
字體:
來源:轉載
供稿:網友
在談述函數調用和返回值問題之前,先來看看C++中內存分配的問題。
C++編譯器將計算機內存分為代碼區和數據區,很顯然,代碼區就是存放程序代碼,而數據區則是存放程序編譯和執行過程出現的變量和常量。數據區又分為靜態數據區、動態數據區,動態數據區包括堆區和棧區。
以下是各個區的作用:
(1)代碼區:存放程序代碼;
(2)數據區
a.靜態數據區: 在編譯器進行編譯的時候就為該變量分配的內存,存放在這個區的數據在程序全部執行結束后系統自動釋放,生命周期貫穿于整個程序執行過程。
b.動態數據區:包括堆區和棧區
堆區:這部分存儲空間完全由程序員自己負責管理,它的分配和釋放都由程序員自己負責。這個區是唯一一個可以由程序員自己決定變量生存期的區間??梢杂胢alloc,new申請對內存,并通過free和delete釋放空間。如果程序員自己在堆區申請了空間,又忘記將這片內存釋放掉,就會造成內存泄露的問題,導致后面一直無法訪問這片存儲區域。
棧區:存放函數的形式參數和局部變量,由編譯器分配和自動釋放,函數執行完后,局部變量和形參占用的空間會自動被釋放。效率比較高,但是分配的容量很有限。
注意:
1)全局變量以及靜態變量存放在靜態數據區;
2)注意常量的存放區域,通常情況下,常量存放在程序區(程序區是只讀的,因此任何修改常量的行為都是非法的),而不是數據區。有的系統,也將部分常量分配到靜態數據區,比如字符串常量(有的系統也將其分配在程序區)。但是要記住一點,常量所在的內存空間都是受系統保護的,不能修改。對常量空間的修改將造成訪問內存出錯,一般系統都會提示。常量的生命周期一直到程序執行結束為止。
在弄懂內存分配的問題過后,來看看函數調用的過程:
執行某個函數時,如果有參數,則在棧上為形式參數分配空間(如果是引用類型的參數則類外),繼續進入到函數體內部,如果遇到變量,則按情況為變量在不同的存儲區域分配空間(如果是static類型的變量,則是在進行編譯的過程中已經就分配了空間),函數內的語句執行完后,如果函數沒有返回值,則直接返回調用該函數的地方(即執行遠點),如果存在返回值,則先將返回值進行拷貝傳回,再返回執行遠點,函數全部執行完畢后,進行退棧操作,將剛才函數內部在棧上申請的內存空間釋放掉。
下面通過幾個例子來談談內存分配函數返回值的問題:
內存分配的問題:
復制代碼 代碼如下:

int a=1;           a在棧區
char s[]="123";    s在棧區,“123”在棧區,其值可以被修改
char *s="123";     s在棧區,“123”在常量區,其值不能被修改
int *p=new int;    p在棧區,申請的空間在堆區(p指向的區域)
int *p=(int *)malloc(sizeof(int)); p在棧區,p指向的空間在堆區
static int b=0;    b在靜態區

1.test1 
復制代碼 代碼如下:

#include<iostream>
using namespace std;
void test(int *p)
{
    int b=2;
    p=&b;
    cout<<p<<endl;
}
int main(void)
{
    int a=10;
    int *p=&a;
    cout<<p<<endl;
    test(p);
    cout<<p<<endl;
    return 0;
}

第一行輸出和第三行輸出的結果相同,而第一行、第三行與第二行輸出的結果不同。從這里可以看出,當指針作為參數進行傳遞時傳遞的也只是一個值,只不過該值只一個地址,因此對于形參的改變并不影響實參。
2.test2
復制代碼 代碼如下:

#include<iostream>
using namespace std;
char* test(void)
{
    char str[]="hello world!";
    return str;
}
int main(void)
{
    char *p;
    p=test();
    cout<<p<<endl;
    return 0;
}

輸出結果可能是hello world!,也可能是亂麻。
出現這種情況的原因在于:在test函數內部聲明的str數組以及它的值"hello world”是在棧上保存的,當用return將str的值返回時,將str的值拷貝一份傳回,當test函數執行結束后,會自動釋放棧上的空間,即存放hello world的單元可能被重新寫入數據,因此雖然main函數中的指針p是指向存放hello world的單元,但是無法保證test函數執行完后該存儲單元里面存放的還是hello world,所以打印出的結果有時候是hello world,有時候是亂麻。
3.test3 
復制代碼 代碼如下:

#include<iostream>
using namespace std;
int test(void)
{
    int a=1;
    return a;
}
int main(void)
{
    int b;
    b=test();
    cout<<b<<endl;
    return 0;
}

輸出結果為 1
有人會問為什么這里傳回來的值可以正確打印出來,不是棧會被刷新內容么?是的,確實,在test函數執行完后,存放a值的單元是可能會被重寫,但是在函數執行return時,會創建一個int型的零時變量,將a的值復制拷貝給該零時變量,因此返回后能夠得到正確的值,即使存放a值的單元被重寫數據,但是不會受到影響。
4.test4
復制代碼 代碼如下:

#include<iostream>
using namespace std;
char* test(void)
{
    char *p="hello world!";
    return p;
}
int main(void)
{
    char *str;
    str=test();
    cout<<str<<endl;
    return 0;
}

執行結果是 hello world!
同樣返回的是指針,為什么這里會正確地打印出hello world1?這是因為char *p="hello world!",指針p是存放在棧上的,但是"hello world!”是一個常量字符串,因此存放在常量區,而常量區的變量的生存期與整個程序執行的生命期是一樣的,因此在test函數執行完后,str指向存放“hello world!”的單元,并且該單元里的內容在程序沒有執行完是不會被修改的,因此可以正確輸出結果。
5.test5
復制代碼 代碼如下:

#include<iostream>
using namespace std;
char* test(void)
{
    char *p=(char *)malloc(sizeof(char)*100);
    strcpy(p,"hello world");
    return p;
}
int main(void)
{
    char *str;
    str=test();
    cout<<str<<endl;
    return 0;
}

運行結果 hello world
這種情況下同樣可以輸出正確的結果,是因為是用malloc在堆上申請的空間,這部分空間是由程序員自己管理的,如果程序員沒有手動釋放堆區的空間,那么存儲單元里的內容是不會被重寫的,因此可以正確輸出結果。
6.test6
復制代碼 代碼如下:

#include<iostream>
using namespace std;
void test(void)
{
    char *p=(char *)malloc(sizeof(char)*100);
    strcpy(p,"hello world");
    free(p);
    if(p==NULL)
    {
        cout<<"NULL"<<endl;
    }
}
int main(void)
{
    test();
    return 0;
}

沒有輸出
在這里注意了,free()釋放的是指針指向的內存!注意!釋放的是內存,不是指針!這點非常非常重 要!指針是一個變量,只有程序結束時才被銷毀。釋放了內存空間后,原來指向這塊空間的指針還是存在!只不過現在指針指向的內容的垃圾,是未定義的,所以說是垃圾。因此,釋放內存后應把把指針指向NULL,防止指針在后面不小心又被使用,造成無法估計的后果。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成人1234| 久久精品一区中文字幕| 欧美香蕉大胸在线视频观看| 91精品国产一区| 国产精品一区二区三区毛片淫片| 亚洲自拍偷拍在线| 国产欧美va欧美va香蕉在| 日韩中文字幕国产| 91精品国产高清久久久久久91| 精品视频一区在线视频| 亚洲已满18点击进入在线看片| 在线精品高清中文字幕| 一区二区三区 在线观看视| 亚洲国产精品成人精品| 亚洲国内精品在线| 91精品国产91久久久久久不卡| 国产精品白嫩美女在线观看| 久久99精品久久久久久青青91| 国产欧美日韩综合精品| 精品国产91乱高清在线观看| 亚洲国产高清福利视频| 色噜噜狠狠狠综合曰曰曰88av| 欧美成人第一页| 欧美一区亚洲一区| 国产精品自拍小视频| 久久不射热爱视频精品| 久久精品视频在线播放| 欧美老女人性生活| 国产97在线|日韩| 亚洲国产免费av| 国产精品久久久久久久美男| 久久久国产一区二区| 人体精品一二三区| 国产亚洲欧美日韩一区二区| 欧美成人h版在线观看| 一个人看的www欧美| 久久色免费在线视频| 国产在线精品一区免费香蕉| 欧亚精品中文字幕| 久久不射热爱视频精品| 亚洲精品免费一区二区三区| 欧美电影免费观看高清| 欧美日韩国产第一页| 97国产成人精品视频| 日韩国产精品一区| 国产在线不卡精品| 日本精品性网站在线观看| 国产男人精品视频| 亚洲人成网在线播放| 成人写真视频福利网| 亚洲黄色www网站| 亚洲视频在线视频| 欧美激情视频网站| 国产成人精品在线视频| 精品色蜜蜜精品视频在线观看| 亚洲一二在线观看| 最新69国产成人精品视频免费| 国产日韩欧美黄色| www.日本久久久久com.| 亚洲第一区中文字幕| 欧美国产日韩中文字幕在线| 国产精品美女av| 欧美日在线观看| 欧美性色xo影院| 中文字幕日韩精品在线| 亚洲精品一区中文字幕乱码| 在线精品视频视频中文字幕| 欧美最顶级的aⅴ艳星| 久久99精品久久久久久琪琪| 欧美中文在线字幕| 欧美成人自拍视频| 2024亚洲男人天堂| 国产精品视频久| 78m国产成人精品视频| 久久久久久久久久久成人| 超碰精品一区二区三区乱码| 国产精品中文字幕久久久| 国产精品久久久久久久久久| 日韩国产激情在线| 欧美黄网免费在线观看| 亚洲天堂av图片| 亚洲一区二区三区在线视频| 欧美综合在线第二页| 欧美精品免费在线观看| 亚洲欧美国产制服动漫| 久久久精品影院| 成人精品视频久久久久| 精品久久久久久国产91| 在线日韩精品视频| 欧美野外wwwxxx| 精品自拍视频在线观看| 色综合久久88色综合天天看泰| 国产视频精品在线| 欧美日韩国产丝袜另类| 91亚洲精品在线| 成人欧美在线观看| 日韩亚洲在线观看| 欧美国产日韩一区二区在线观看| 亚洲性线免费观看视频成熟| 欧美大荫蒂xxx| 国产精品99久久久久久人| 亚洲夜晚福利在线观看| 国产精品自拍小视频| 欧美大片欧美激情性色a∨久久| 日本成熟性欧美| 91成品人片a无限观看| 欧美最近摘花xxxx摘花| 黑人极品videos精品欧美裸| 亚洲sss综合天堂久久| 久久伊人精品一区二区三区| 欧美日韩高清区| 美女视频黄免费的亚洲男人天堂| 久久久久久这里只有精品| 久久亚洲国产精品成人av秋霞| 久久精品免费电影| 亚洲第一福利视频| 日韩在线视频线视频免费网站| 黄色一区二区在线观看| 国产精品对白刺激| 国产91ⅴ在线精品免费观看| 久久久久久亚洲| 亚洲第一页中文字幕| 日韩视频永久免费观看| 狠狠综合久久av一区二区小说| 亚洲男人av电影| 欧美成人激情在线| 日韩精品中文字幕在线观看| 国产精品免费小视频| 久久精品亚洲国产| 久久久极品av| 色婷婷综合久久久久中文字幕1| 最近的2019中文字幕免费一页| 亚洲精品短视频| 91久久久久久久久久久| 亚洲精品国产成人| 国产精品视频专区| 亚洲精品久久久久中文字幕欢迎你| 7777精品视频| 夜夜嗨av一区二区三区免费区| 97成人精品视频在线观看| 国产精品男女猛烈高潮激情| 精品视频在线播放色网色视频| 久久99热精品这里久久精品| 国产亚洲精品久久久| 亚洲国产精品电影在线观看| 91亚洲精品在线观看| 欧美电影在线播放| 国产成+人+综合+亚洲欧美丁香花| 亚洲欧美日韩网| 91久久精品美女| 国产精品男人的天堂| 亚洲精品动漫100p| 色偷偷av一区二区三区| 91在线网站视频| 欧洲亚洲免费在线| 国产精品入口免费视| 国产成人久久久精品一区| 黑丝美女久久久| 精品国偷自产在线| 欧洲永久精品大片ww免费漫画| 国产国产精品人在线视| 欧美性猛交xxxx乱大交极品| 国产精品入口夜色视频大尺度| 亚洲第一av网|