最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C語(yǔ)言中的動(dòng)態(tài)內(nèi)存管理

 更新時(shí)間:2022年12月12日 10:02:57   作者:小馬學(xué)習(xí)代碼  
對(duì)于數(shù)據(jù)的存儲(chǔ)我們可以靜態(tài)存儲(chǔ),也可以動(dòng)態(tài)存儲(chǔ),兩種方式都有自己特有的好處,這篇文章教我們?nèi)绾瓦M(jìn)行動(dòng)態(tài)的數(shù)據(jù)存儲(chǔ)?。。?!感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、動(dòng)態(tài)內(nèi)存管理

1.1為什么要有動(dòng)態(tài)內(nèi)存管理

1.1.1  在c語(yǔ)言中我們普通的內(nèi)存開(kāi)辟是直接在棧上進(jìn)行開(kāi)辟的 

int i = 20;//在棧空間上開(kāi)辟四個(gè)字節(jié)
int arr[10]={0}; //在棧中連續(xù)開(kāi)辟四十個(gè)字節(jié)

這樣開(kāi)辟的特點(diǎn)是:

(1)他所開(kāi)辟的空間是固定的 

(2)數(shù)組在申明的時(shí)候,必須指定數(shù)組的長(zhǎng)度,它所需要的內(nèi)存在編譯時(shí)分配

但對(duì)于空間的需求,我們有的時(shí)候并不知道,有可能空間開(kāi)大了造成了浪費(fèi),也有可能空間開(kāi)小了造成棧溢出,這樣我們就需要一個(gè)動(dòng)態(tài)的內(nèi)存管理讓我們需要多少內(nèi)存的時(shí)候開(kāi)辟多少。

1.2動(dòng)態(tài)內(nèi)存介紹

1.2.1malloc 和 free

void*   malloc  (size_t size);

這個(gè)函數(shù)想內(nèi)存中申請(qǐng)一個(gè)連續(xù)的空間(是在堆中申請(qǐng)),并返回指向這塊空間的指針。 

如果開(kāi)辟成功,則返回一個(gè)指向開(kāi)辟好空間的指針。

如果開(kāi)辟失敗,則返回一個(gè)NULL指針,因此malloc的返回值一定要做檢查。

返回值的類型是 void* ,所以malloc函數(shù)并不知道開(kāi)辟空間的類型,具體在使用的時(shí)候使用者自己 來(lái)決定。

如果參數(shù) size 為0,malloc的行為是標(biāo)準(zhǔn)是未定義的,取決于編譯器。

同樣的C語(yǔ)言提供了另外一個(gè)函數(shù)free,專門是用來(lái)做動(dòng)態(tài)內(nèi)存的釋放和回收的

void * free (void * ptr) 

free 是用來(lái)釋放動(dòng)態(tài)開(kāi)辟的內(nèi)存的 

如果參數(shù) ptr 指向的空間不是動(dòng)態(tài)開(kāi)辟的,那free函數(shù)的行為是未定義的。

如果參數(shù) ptr 是NULL指針,則函數(shù)什么事都不做。

#include<stdio.h>
#include<stdlib.h>  //malloc 和free 都在stdlib.h的頭文件里
int main()
{
    int arr[10] ={0}; //這是在棧中申請(qǐng)連續(xù)的四十個(gè)空間 是靜態(tài)的
    int * arr1;
    int *ptr ;
    ptr =(int*)malloc (10*sizeof(int)); //申請(qǐng)一個(gè)動(dòng)態(tài)內(nèi)存空間為40字節(jié)
    if(ptr==NULL) //防止申請(qǐng)空間失敗傳入了空指針
    {
        perror("ptr");
    }
    arr1=ptr;
    free(arr1);  //結(jié)束后要進(jìn)行一個(gè)空間的釋放
    arr1=NULL;      //然后在指向空指針?lè)乐钩霈F(xiàn)了野指針
    //這就是申請(qǐng)一個(gè)動(dòng)態(tài)內(nèi)存空間的套用過(guò)程
    
    return 0;
}

1.2.2 calloc

c語(yǔ)言同樣的提供了一個(gè)函數(shù)calloc,也是用來(lái)動(dòng)態(tài)內(nèi)存的分配

void* calloc (size_t num, size_t size);

函數(shù)的功能是為 num 個(gè)大小為 size 的元素開(kāi)辟一塊空間,并且把空間的每個(gè)字節(jié)初始化為0。

與函數(shù) malloc 的區(qū)別只在于 calloc 會(huì)在返回地址之前把申請(qǐng)的空間的每個(gè)字節(jié)初始化為全0。

#include<stdio.h>
#include<stdlib.h>  //malloc 和free 都在stdlib.h的頭文件里
int main()
{
    int arr[10] ={0}; //這是在棧中申請(qǐng)連續(xù)的四十個(gè)空間 是靜態(tài)的
    int * arr1;
    int *ptr ;
    ptr =(int*)calloc (10,sizeof(int)); //申請(qǐng)一個(gè)動(dòng)態(tài)內(nèi)存空間為40字節(jié)
    if(ptr==NULL) //防止申請(qǐng)空間失敗傳入了空指針
    {
        perror("ptr");
    }
    arr1=ptr;
    free(arr1);  //結(jié)束后要進(jìn)行一個(gè)空間的釋放
    arr1=NULL;      //然后在指向空指針?lè)乐钩霈F(xiàn)了野指針
    //這就是申請(qǐng)一個(gè)動(dòng)態(tài)內(nèi)存空間的套用過(guò)程
    
    return 0;
}

1.2.3 realloc

realloc 使我們申請(qǐng)的的動(dòng)態(tài)內(nèi)存空間變得靈活,在申請(qǐng)動(dòng)態(tài)內(nèi)存空間的時(shí)候,有時(shí)候我們申請(qǐng)的過(guò)大,或者申請(qǐng)的過(guò)小的時(shí)候,我們可以通過(guò)realloc也對(duì)我們申請(qǐng)的空間進(jìn)行一個(gè)合理的調(diào)整改變

void* realloc (void* ptr, size_t size);

  • ptr 是要調(diào)整的內(nèi)存地址
  • size 調(diào)整之后新大小
  • 返回值為調(diào)整之后的內(nèi)存起始位置

這個(gè)函數(shù)調(diào)整原內(nèi)存空間大小的基礎(chǔ)上,還會(huì)將原來(lái)內(nèi)存中的數(shù)據(jù)移動(dòng)到 新 的空間。

這有兩種調(diào)節(jié):

第一種是在你原來(lái)的內(nèi)存上進(jìn)行了一個(gè)改變(內(nèi)存改變不大),就是在原有的內(nèi)存空間進(jìn)行加大空間。

第二種就是原有空間之后沒(méi)有足夠多的空間時(shí),擴(kuò)展的方法是:在堆空間上另找一個(gè)合適大小的連續(xù)空間來(lái)使用。這樣函數(shù)返回的是一個(gè)新的內(nèi)存地址。

#include<stdio.h>
#include<stdlib.h>  //malloc 和free 都在stdlib.h的頭文件里
int main()
{
    int arr[10] ={0}; //這是在棧中申請(qǐng)連續(xù)的四十個(gè)空間 是靜態(tài)的
    int * arr1;
    int *ptr ;
    ptr =(int*)calloc (10,sizeof(int)); //申請(qǐng)一個(gè)動(dòng)態(tài)內(nèi)存空間為40字節(jié)
    if(ptr==NULL) //防止申請(qǐng)空間失敗傳入了空指針
    {
        perror("ptr");
    }
    arr1=ptr;
    arr1 =(int*)realloc (arr1,10000);  //改變?cè)械膬?nèi)存空間
    free(arr1);
    arr1=NULL;
    ptr=NULL; 
    return 0;
}

1.3常見(jiàn)的動(dòng)態(tài)內(nèi)存錯(cuò)誤

1.3.1對(duì)NULL指針解引用操作

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *ptr;
    ptr=(int*)malloc(sizeof(int));
    *ptr=1;  //這里有可能申請(qǐng)失敗 ,但我這沒(méi)有失敗,為了以防萬(wàn)一還是需要進(jìn)行判斷一下,正確的申請(qǐng)?jiān)谏厦?
    free(ptr);
    ptr=NULL;
    
    
    return 0;
}

1.3.2對(duì)動(dòng)態(tài)內(nèi)存的越界

#include<stdio.h>
#include<stdlib.h>  //malloc 和free 都在stdlib.h的頭文件里
int main()
{
    int *ptr ;
    ptr =(int*)malloc(40); //申請(qǐng)一個(gè)動(dòng)態(tài)內(nèi)存空間為40字節(jié)
    if(ptr==NULL) //防止申請(qǐng)空間失敗傳入了空指針
    {
        perror("ptr");
    }
    
    for(int i=0;i<=11;i++)
    {
        *(ptr+i)=i;   //申請(qǐng)的是四十個(gè)字節(jié),這里產(chǎn)生了越界
    }
    for(int i=0;i<=11;i++)
    {
        printf("%d ",*(ptr+i));
    }
    free(ptr);
    ptr=NULL;
    return 0;
}

1.3.3對(duì)非動(dòng)態(tài)空間進(jìn)行釋放

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p;
    *p=10;  
    free(p);  //這里的p并不是動(dòng)態(tài)內(nèi)存空間仍然進(jìn)行了釋放
    return 0;
}

1.3.4 動(dòng)態(tài)內(nèi)存空間的部分釋放

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p=(int*)malloc(sizeof(int)*2);
    if(p==NULL)
    {
        perror("p");
    }
    p++;
    free(p); //這里的p的地址并不是起始地址,只是進(jìn)行了部分的釋放
    p=NULL;
   
}

1.3.5對(duì)一塊動(dòng)態(tài)內(nèi)存進(jìn)行多次釋放

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p=(int*)malloc(sizeof(int)*2);
    if(p==NULL)
    {
        perror("p");
    }
    
    free(p);
   // ~~~~~~~~~~
    free(p);  //  已經(jīng)釋放p了有進(jìn)行了釋放
    p=NULL;
   
}

這個(gè)真的有可能發(fā)生,當(dāng)我們代碼寫的比較長(zhǎng)的時(shí)候,我們有可能忘了我們是否已經(jīng)釋放這塊空間,就有可能進(jìn)行重復(fù)的釋放,這是不正確的,而解決他的方法是,當(dāng)我們釋放了一塊空間后,一定讓他指為空指針。

1.3.6動(dòng)態(tài)內(nèi)存忘記釋放(內(nèi)存泄漏)

#include<stdio.h>
#include<stdlib.h>
void test(int *p)
{
     p=(int*)malloc(sizeof(int)*2);
    if(p==NULL)
    {
        perror("p");
    }
}
int main()
{
    int *ptr;
    test(ptr); //這里就是沒(méi)有對(duì)內(nèi)存進(jìn)行釋放
   
}

總結(jié):

對(duì)于動(dòng)態(tài)內(nèi)存還是比較重要的,因?yàn)槎训目臻g是比棧的空間的是大的,同時(shí)我們要知道,動(dòng)態(tài)的是可以進(jìn)行修改的,我們需要多少內(nèi)存就可以開(kāi)辟多少內(nèi)存,防止了內(nèi)存的浪費(fèi),但是我們?cè)谏暾?qǐng)動(dòng)態(tài)內(nèi)存的時(shí)候一定要防止一些不必要的錯(cuò)誤不然就會(huì)得不償失。

以上就是詳解C語(yǔ)言中的動(dòng)態(tài)內(nèi)存管理的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言動(dòng)態(tài)內(nèi)存管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++定時(shí)器Timer在項(xiàng)目中的使用方法

    C++定時(shí)器Timer在項(xiàng)目中的使用方法

    這篇文章主要給大家介紹了關(guān)于C++定時(shí)器Timer在項(xiàng)目中的基本使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • C語(yǔ)言?柔性數(shù)組的使用詳解

    C語(yǔ)言?柔性數(shù)組的使用詳解

    柔性數(shù)組(Flexible?Array)是引入的一個(gè)新特性,它允許你在定義結(jié)構(gòu)體時(shí)創(chuàng)建一個(gè)空數(shù)組,而這個(gè)數(shù)組的大小可以在程序運(yùn)行的過(guò)程中根據(jù)你的需求進(jìn)行更改特別注意的一點(diǎn)是:這個(gè)空數(shù)組必須聲明為結(jié)構(gòu)體的最后一個(gè)成員,并且還要求這樣的結(jié)構(gòu)體至少包含一個(gè)其他類型的成員
    2022-03-03
  • VScode+ESP32簡(jiǎn)單環(huán)境搭建

    VScode+ESP32簡(jiǎn)單環(huán)境搭建

    本文章向大家介紹ESP32-C3搭建環(huán)境教程,主要包括ESP32-C3搭建環(huán)境教程使用實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 深入解析C語(yǔ)言中typedef的四個(gè)用途

    深入解析C語(yǔ)言中typedef的四個(gè)用途

    以下是對(duì)C語(yǔ)言中typedef的四個(gè)用途進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • C++中的6種構(gòu)造函數(shù)舉例詳解

    C++中的6種構(gòu)造函數(shù)舉例詳解

    這篇文章主要介紹了C++中的6種構(gòu)造函數(shù)的相關(guān)資料,C++中構(gòu)造函數(shù)用于類對(duì)象初始化,類型包括默認(rèn)構(gòu)造函數(shù)、參數(shù)化構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)等,默認(rèn)構(gòu)造函數(shù)通常不需要參數(shù),編譯器會(huì)自動(dòng)生成,除非存在其他構(gòu)造函數(shù),需要的朋友可以參考下
    2024-10-10
  • Qt實(shí)現(xiàn)字幕滾動(dòng)效果的示例代碼

    Qt實(shí)現(xiàn)字幕滾動(dòng)效果的示例代碼

    這篇文章主要介紹了Qt如何利用QTimer實(shí)現(xiàn)字幕滾動(dòng)功能,并且可以實(shí)現(xiàn)自行更改文本內(nèi)容、自適應(yīng)文本大小、自由調(diào)整速度等功能,感興趣的可以學(xué)習(xí)一下
    2022-06-06
  • 詳解C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之棧

    詳解C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之棧

    這篇文章主要為大家介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之棧,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • C++設(shè)計(jì)模式編程中Facade外觀模式的使用實(shí)例解析

    C++設(shè)計(jì)模式編程中Facade外觀模式的使用實(shí)例解析

    這篇文章主要介紹了C++設(shè)計(jì)模式編程中Facade外觀模式的使用實(shí)例解析,外觀模式的主要用途就是為子系統(tǒng)的復(fù)雜處理過(guò)程提供方便的調(diào)用方法,需要的朋友可以參考下
    2016-03-03
  • 數(shù)據(jù)結(jié)構(gòu)之AVL樹(shù)詳解

    數(shù)據(jù)結(jié)構(gòu)之AVL樹(shù)詳解

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)之AVL樹(shù)詳解,本文非常細(xì)致的講解了AVL樹(shù)的基礎(chǔ)知識(shí)、AVL樹(shù)的旋轉(zhuǎn)操作、AVL數(shù)的插入和刪除操作等,需要的朋友可以參考下
    2014-08-08
  • C語(yǔ)言中char*和char[]用法區(qū)別分析

    C語(yǔ)言中char*和char[]用法區(qū)別分析

    這篇文章主要介紹了C語(yǔ)言中char*和char[]用法區(qū)別,包括使用過(guò)程中的誤區(qū)及注意點(diǎn)分析,需要的朋友可以參考下
    2014-09-09

最新評(píng)論

双城市| 淮滨县| 白玉县| 宁安市| 秭归县| 通渭县| 北流市| 林周县| 临汾市| 三门峡市| 张北县| 白城市| 阿坝县| 桦南县| 和田县| 囊谦县| 稻城县| 塔河县| 西青区| 沂源县| 庆城县| 新龙县| 拜城县| 三江| 建德市| 新疆| 凤城市| 南召县| 盘锦市| 维西| 银川市| 安宁市| 炉霍县| 平武县| 通州区| 天水市| 无锡市| 临沂市| 嘉禾县| 盈江县| 安西县|