国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C/C++ - 基于C++內(nèi)存分配、函數(shù)調(diào)用與返回值的深入分析

基于C++內(nèi)存分配、函數(shù)調(diào)用與返回值的深入分析

2020-12-11 15:37C++教程網(wǎng) C/C++

本篇文章是對(duì)C++中的內(nèi)存分配、函數(shù)調(diào)用與返回值進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下

在談述函數(shù)調(diào)用和返回值問(wèn)題之前,先來(lái)看看C++中內(nèi)存分配的問(wèn)題。
C++編譯器將計(jì)算機(jī)內(nèi)存分為代碼區(qū)和數(shù)據(jù)區(qū),很顯然,代碼區(qū)就是存放程序代碼,而數(shù)據(jù)區(qū)則是存放程序編譯和執(zhí)行過(guò)程出現(xiàn)的變量和常量。數(shù)據(jù)區(qū)又分為靜態(tài)數(shù)據(jù)區(qū)、動(dòng)態(tài)數(shù)據(jù)區(qū),動(dòng)態(tài)數(shù)據(jù)區(qū)包括堆區(qū)和棧區(qū)。
以下是各個(gè)區(qū)的作用:
(1)代碼區(qū):存放程序代碼;
(2)數(shù)據(jù)區(qū)

a.靜態(tài)數(shù)據(jù)區(qū): 在編譯器進(jìn)行編譯的時(shí)候就為該變量分配的內(nèi)存,存放在這個(gè)區(qū)的數(shù)據(jù)在程序全部執(zhí)行結(jié)束后系統(tǒng)自動(dòng)釋放,生命周期貫穿于整個(gè)程序執(zhí)行過(guò)程。
b.動(dòng)態(tài)數(shù)據(jù)區(qū):包括堆區(qū)和棧區(qū)

堆區(qū):這部分存儲(chǔ)空間完全由程序員自己負(fù)責(zé)管理,它的分配和釋放都由程序員自己負(fù)責(zé)。這個(gè)區(qū)是唯一一個(gè)可以由程序員自己決定變量生存期的區(qū)間。可以用malloc,new申請(qǐng)對(duì)內(nèi)存,并通過(guò)free和delete釋放空間。如果程序員自己在堆區(qū)申請(qǐng)了空間,又忘記將這片內(nèi)存釋放掉,就會(huì)造成內(nèi)存泄露的問(wèn)題,導(dǎo)致后面一直無(wú)法訪(fǎng)問(wèn)這片存儲(chǔ)區(qū)域。
棧區(qū):存放函數(shù)的形式參數(shù)和局部變量,由編譯器分配和自動(dòng)釋放,函數(shù)執(zhí)行完后,局部變量和形參占用的空間會(huì)自動(dòng)被釋放。效率比較高,但是分配的容量很有限。
注意:
1)全局變量以及靜態(tài)變量存放在靜態(tài)數(shù)據(jù)區(qū);
2)注意常量的存放區(qū)域,通常情況下,常量存放在程序區(qū)(程序區(qū)是只讀的,因此任何修改常量的行為都是非法的),而不是數(shù)據(jù)區(qū)。有的系統(tǒng),也將部分常量分配到靜態(tài)數(shù)據(jù)區(qū),比如字符串常量(有的系統(tǒng)也將其分配在程序區(qū))。但是要記住一點(diǎn),常量所在的內(nèi)存空間都是受系統(tǒng)保護(hù)的,不能修改。對(duì)常量空間的修改將造成訪(fǎng)問(wèn)內(nèi)存出錯(cuò),一般系統(tǒng)都會(huì)提示。常量的生命周期一直到程序執(zhí)行結(jié)束為止。
在弄懂內(nèi)存分配的問(wèn)題過(guò)后,來(lái)看看函數(shù)調(diào)用的過(guò)程:
執(zhí)行某個(gè)函數(shù)時(shí),如果有參數(shù),則在棧上為形式參數(shù)分配空間(如果是引用類(lèi)型的參數(shù)則類(lèi)外),繼續(xù)進(jìn)入到函數(shù)體內(nèi)部,如果遇到變量,則按情況為變量在不同的存儲(chǔ)區(qū)域分配空間(如果是static類(lèi)型的變量,則是在進(jìn)行編譯的過(guò)程中已經(jīng)就分配了空間),函數(shù)內(nèi)的語(yǔ)句執(zhí)行完后,如果函數(shù)沒(méi)有返回值,則直接返回調(diào)用該函數(shù)的地方(即執(zhí)行遠(yuǎn)點(diǎn)),如果存在返回值,則先將返回值進(jìn)行拷貝傳回,再返回執(zhí)行遠(yuǎn)點(diǎn),函數(shù)全部執(zhí)行完畢后,進(jìn)行退棧操作,將剛才函數(shù)內(nèi)部在棧上申請(qǐng)的內(nèi)存空間釋放掉。
下面通過(guò)幾個(gè)例子來(lái)談?wù)?font style="COLOR: #ff0000">內(nèi)存分配和函數(shù)返回值的問(wèn)題:
內(nèi)存分配的問(wèn)題:

復(fù)制代碼 代碼如下:


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


1.test1

復(fù)制代碼 代碼如下:


#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;
}


第一行輸出和第三行輸出的結(jié)果相同,而第一行、第三行與第二行輸出的結(jié)果不同。從這里可以看出,當(dāng)指針作為參數(shù)進(jìn)行傳遞時(shí)傳遞的也只是一個(gè)值,只不過(guò)該值只一個(gè)地址,因此對(duì)于形參的改變并不影響實(shí)參。
2.test2

復(fù)制代碼 代碼如下:


#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;
}


輸出結(jié)果可能是hello world!,也可能是亂麻。
出現(xiàn)這種情況的原因在于:在test函數(shù)內(nèi)部聲明的str數(shù)組以及它的值"hello world”是在棧上保存的,當(dāng)用return將str的值返回時(shí),將str的值拷貝一份傳回,當(dāng)test函數(shù)執(zhí)行結(jié)束后,會(huì)自動(dòng)釋放棧上的空間,即存放hello world的單元可能被重新寫(xiě)入數(shù)據(jù),因此雖然main函數(shù)中的指針p是指向存放hello world的單元,但是無(wú)法保證test函數(shù)執(zhí)行完后該存儲(chǔ)單元里面存放的還是hello world,所以打印出的結(jié)果有時(shí)候是hello world,有時(shí)候是亂麻。
3.test3 

復(fù)制代碼 代碼如下:


#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;
}


輸出結(jié)果為 1
有人會(huì)問(wèn)為什么這里傳回來(lái)的值可以正確打印出來(lái),不是棧會(huì)被刷新內(nèi)容么?是的,確實(shí),在test函數(shù)執(zhí)行完后,存放a值的單元是可能會(huì)被重寫(xiě),但是在函數(shù)執(zhí)行return時(shí),會(huì)創(chuàng)建一個(gè)int型的零時(shí)變量,將a的值復(fù)制拷貝給該零時(shí)變量,因此返回后能夠得到正確的值,即使存放a值的單元被重寫(xiě)數(shù)據(jù),但是不會(huì)受到影響。
4.test4

復(fù)制代碼 代碼如下:


#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;
}


執(zhí)行結(jié)果是 hello world!
同樣返回的是指針,為什么這里會(huì)正確地打印出hello world1?這是因?yàn)閏har *p="hello world!",指針p是存放在棧上的,但是"hello world!”是一個(gè)常量字符串,因此存放在常量區(qū),而常量區(qū)的變量的生存期與整個(gè)程序執(zhí)行的生命期是一樣的,因此在test函數(shù)執(zhí)行完后,str指向存放“hello world!”的單元,并且該單元里的內(nèi)容在程序沒(méi)有執(zhí)行完是不會(huì)被修改的,因此可以正確輸出結(jié)果。
5.test5

復(fù)制代碼 代碼如下:


#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;
}


運(yùn)行結(jié)果 hello world
這種情況下同樣可以輸出正確的結(jié)果,是因?yàn)槭怯胢alloc在堆上申請(qǐng)的空間,這部分空間是由程序員自己管理的,如果程序員沒(méi)有手動(dòng)釋放堆區(qū)的空間,那么存儲(chǔ)單元里的內(nèi)容是不會(huì)被重寫(xiě)的,因此可以正確輸出結(jié)果。
6.test6

復(fù)制代碼 代碼如下:


#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;
}


沒(méi)有輸出
在這里注意了,free()釋放的是指針指向的內(nèi)存!注意!釋放的是內(nèi)存,不是指針!這點(diǎn)非常非常重 要!指針是一個(gè)變量,只有程序結(jié)束時(shí)才被銷(xiāo)毀。釋放了內(nèi)存空間后,原來(lái)指向這塊空間的指針還是存在!只不過(guò)現(xiàn)在指針指向的內(nèi)容的垃圾,是未定義的,所以說(shuō)是垃圾。因此,釋放內(nèi)存后應(yīng)把把指針指向NULL,防止指針在后面不小心又被使用,造成無(wú)法估計(jì)的后果。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色综久久| 中文字幕一区在线观看视频 | 欧美日韩激情在线 | 久久精品无码一区二区三区 | 欧美激情一区二区三级高清视频 | 午夜精品福利在线观看 | 成人免费淫片aa视频免费 | 999精品视频 | 久色 | 精品久久久久久 | 国产高清在线精品一区二区三区 | 国产一级片 | 亚洲www啪成人一区二区 | 成年人免费在线观看网站 | 丁香伊人 | 欧美成人一区二区三区片免费 | 91欧美激情一区二区三区成人 | 久久九九99 | 99精品欧美一区二区三区 | 久久资源av| 精品久久中文 | 媚黑视频| 午夜a区 | 中文字幕国产视频 | 免费av一区二区三区 | 久久精品亚洲成在人线av网址 | www欧美| 久久久久久久久国产成人免费 | 欧美一区二区三区在线观看视频 | 国产精品毛片久久久久久久av | 曰韩一级鸥美一级 | 99青草| 中文字幕一区二区三区四区五区 | 成人影院一区二区 | 蜜桃一区| 国产婷婷精品av在线 | 成人毛片在线 | 在线观看91视频 | 久久久久久久久综合 | 欧美久久综合 | 激情综合久久 |