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

詳細(xì)談?wù)凜語言中動態(tài)內(nèi)存

 更新時(shí)間:2022年03月07日 11:23:26   作者:_w_z_j_  
在C語言中,編寫程序的時(shí)候不能確定內(nèi)存的大小,希望程序在運(yùn)行的過程中根據(jù)數(shù)據(jù)量的大小動態(tài)的分配內(nèi)存,這篇文章主要給大家介紹了關(guān)于C語言中動態(tài)內(nèi)存的相關(guān)資料,需要的朋友可以參考下

前言

關(guān)于動態(tài)內(nèi)存管理,可能有學(xué)習(xí)過的小伙伴,也有沒有聽說過的。沒有聽說過的小伙伴會覺得很奇怪啊,為什么要動態(tài)開辟內(nèi)存,內(nèi)存怎么還能是動態(tài)的。給不知道的小伙伴解釋一下。咱們平時(shí)在內(nèi)存開辟空間也就是在棧區(qū)(局部變量,函數(shù)參數(shù)等等),靜態(tài)區(qū)(全局變量,static修飾的局部變量等等)開辟空間。只能是用多少開辟多少,是非常局限的。有時(shí)候我們需要的空間大小在程序運(yùn)行的時(shí)候才能知道,那數(shù)組的編譯時(shí)開辟空間的方式就不能滿足了,所以就試試動態(tài)內(nèi)存存儲。而動態(tài)內(nèi)存開辟的空間都是在內(nèi)存中的堆空間的。

1.關(guān)于動態(tài)內(nèi)存的函數(shù)

1.1 malloc和free函數(shù)

malloc這個(gè)函數(shù)向內(nèi)存申請一塊連續(xù)可用的空間,并返回指向這塊空間的指針,如果開辟成功,則返回一個(gè)指向開辟好空間的指針;如果開辟失敗,則返回一個(gè)NULL指針,因此malloc的返回值一定要做檢查。

free函數(shù)專門是用來做動態(tài)內(nèi)存的釋放和回收的。如果參數(shù) ptr 指向的空間不是動態(tài)開辟的,那free函數(shù)的行為是未定義的;如果參數(shù) ptr 是NULL指針,則函數(shù)什么事都不做。
 

說明:

該函數(shù)設(shè)計(jì)的巧妙的一點(diǎn)就是返回值為void*,因?yàn)楹瘮?shù)創(chuàng)造者并不知道使用者是想以什么樣的類型指針來接收動態(tài)開辟的空間,所以使用者在使用時(shí)只需要強(qiáng)行轉(zhuǎn)換成自己想要的類型就可以:

int* p = (int*)malloc(40);//假設(shè)是整型時(shí)的例子

在使用完動態(tài)開辟的空間后記得要用free函數(shù)向操作系統(tǒng)釋放開辟的空間,并且將指針賦為空指針:

int* p = (int*)malloc(40);
 
//......
 
free(p);//避免內(nèi)存泄漏
p = NULL;//原指針指向的位置既然已經(jīng)還給操作系統(tǒng)的,就將指針賦為空指針,避免野指針等問題

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

需要引頭文件stdlib.h

1.2 calloc函數(shù)

 calloc可與malloc函數(shù)相對照來學(xué)習(xí),calloc函數(shù)的功能是為 num 個(gè)大小為 size 的元素開辟一塊空間,并且把空間的每個(gè)字節(jié)初始化為0。與malloc有兩點(diǎn)不同:

參數(shù)不同,calloc需要指明開辟空間的數(shù)據(jù)類型和該類型數(shù)據(jù)的個(gè)數(shù),而malloc是全部字節(jié)數(shù);

calloc在開辟空間的同時(shí)將空間內(nèi)的全部字節(jié)初始化為0.

1.3 realloc函數(shù)

 realloc函數(shù)用來調(diào)整開辟空間的大小,有時(shí)可能開辟的空間小了,有時(shí)候可能開辟的大了,都可以通過realloc函數(shù)來修改,并且會將原來內(nèi)存中的數(shù)據(jù)移動到新的空間。

realloc在調(diào)整空間大小時(shí)有兩種情況:

原有空間后有足夠大的空間,這種情況下擴(kuò)展內(nèi)存就直接原有內(nèi)存之后直接追加空間,原來空間的數(shù)據(jù)不發(fā)生變化,返回值為原來位置的指針;

 2.原有空間后沒有足夠大的空間,這時(shí)便在堆空間找到大小合適的連續(xù)空間使用,并將原有空間的數(shù)據(jù)轉(zhuǎn)移到新的空間返回值為新空間的地址。

int main()
{
    int *str = (int*)malloc(10);
    if(str != NULL)
{
    //.....
}
else
{
    exit(EXIT_FAILURE);
}
    //擴(kuò)展容量
//代碼1
str = (int*)realloc(str, 1000);//這樣可以嗎?(如果申請失敗會返回一個(gè)空指針!??!)
 
 
//修改代碼2
int*p = NULL;
p = realloc(str, 1000);
if(p != NULL)
{
    str = p;
}
//...
free(str);
return 0;
}

2.常見的動態(tài)內(nèi)存錯(cuò)誤

2.1 對NULL指針解引用

int* p = (int*)malloc(40);
*p=10;
free(p);

這就是忽略了返回值可能是空指針的可能,如果開辟失敗會返回空指針。所以最好的做法就是判斷一下指針是否為空,然后再進(jìn)行下一步。

int* p = (int*)malloc(40);
if(p != NULL)
{
    *p=10;
}
free(p);

2.2 對動態(tài)內(nèi)存開辟的空間越界訪問

就類似于使用數(shù)組時(shí)對數(shù)組越界訪問。

int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
    exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
    *(p+i) = i;//當(dāng)i是10的時(shí)候越界訪問
}
free(p);

2.3 對非動態(tài)開辟內(nèi)存使用free釋放

int a = 0;
int* p = &a;
free(p);

通過查閱MSDN可以發(fā)現(xiàn):Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors. 就是說如果用free釋放非calloc,malloc,realloc函數(shù)動態(tài)開辟的空間可能會導(dǎo)致后續(xù)的分配請求并且導(dǎo)致錯(cuò)誤。

2.4 使用free釋放一塊動態(tài)開辟內(nèi)存的一部分

int *p = (int *)malloc(100);
p++;
free(p);//p不再指向動態(tài)內(nèi)存的起始位置

會導(dǎo)致動態(tài)開辟的空間無法完全釋放,進(jìn)而可能會導(dǎo)致內(nèi)存泄漏。

2.5 對同一塊動態(tài)內(nèi)存多次釋放

int *p = (int *)malloc(10);
free(p);
free(p);//重復(fù)釋放

2.6 內(nèi)存泄漏

void test()
{
    int *p = (int *)malloc(100);
    if(NULL != p)
    {
        *p = 20;
    }
}
int main()
{
    test();
    return 0;
}

如果使用完動態(tài)內(nèi)存又不釋放則會導(dǎo)致這塊內(nèi)存無法在后續(xù)被利用,導(dǎo)致內(nèi)存泄漏。動態(tài)開辟的空間一定要釋放,并且正確釋放。

補(bǔ)充:為什么要引入動態(tài)內(nèi)存分配

1.指針只能指向一個(gè)確切的內(nèi)存空間,欲使用一個(gè)數(shù)據(jù),必須先設(shè)定一個(gè)變量來保存它么?

2.在程序設(shè)計(jì)時(shí),數(shù)據(jù)多為動態(tài)的。即程序運(yùn)行時(shí)數(shù)據(jù)項(xiàng)的數(shù)量是變化的。

3.用數(shù)組保存多個(gè)元素時(shí),很難預(yù)知實(shí)際運(yùn)行時(shí)存儲的元素個(gè)數(shù),往往會導(dǎo)致預(yù)定義的元素個(gè)數(shù)不足或過多

例如:電話簿的管理程序。當(dāng)添加新聯(lián)系人時(shí),數(shù)據(jù)項(xiàng)將增加;刪除聯(lián)系人時(shí),數(shù)據(jù)項(xiàng)將減少。

動態(tài)數(shù)據(jù)結(jié)構(gòu)可以在運(yùn)行時(shí)靈活地添加、刪除或重排數(shù)據(jù)項(xiàng)。
動態(tài)內(nèi)存管理可以在運(yùn)行時(shí)分配更多的內(nèi)存空間或釋放掉不再需要的空間,因而可以優(yōu)化存儲空間的使用。

所以———由于無法預(yù)知在運(yùn)行時(shí)數(shù)組元素的使用情況,在程序中預(yù)定義的數(shù)組大小,如果過小,會導(dǎo)致程序運(yùn)行失?。蝗绻^大,則會浪費(fèi)內(nèi)存空間。

如果在運(yùn)行時(shí)根據(jù)實(shí)際需要來決定內(nèi)存的使用情況,則可以很好的解決以上問題。

總結(jié)

到此這篇關(guān)于C語言中動態(tài)內(nèi)存的文章就介紹到這了,更多相關(guān)C語言動態(tài)內(nèi)存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++使用BitBlt進(jìn)行窗口抓圖的方法

    C++使用BitBlt進(jìn)行窗口抓圖的方法

    這篇文章主要介紹了C++使用BitBlt進(jìn)行窗口抓圖的方法,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下
    2021-01-01
  • c語言連接mysql數(shù)據(jù)庫的實(shí)現(xiàn)方法

    c語言連接mysql數(shù)據(jù)庫的實(shí)現(xiàn)方法

    C語言連接mysql數(shù)據(jù)庫,需要相應(yīng)的頭文件和lib文件,如果你安裝Mysql數(shù)據(jù)庫,會在安裝目錄下找到這些庫文件,如果沒有安裝,也可以在網(wǎng)上找到
    2012-05-05
  • C語言實(shí)現(xiàn)數(shù)字連連看

    C語言實(shí)現(xiàn)數(shù)字連連看

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)數(shù)字連連看游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++算法之在無序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法

    C++算法之在無序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法

    這篇文章主要介紹了C++算法之在無序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法,涉及C++數(shù)組的遍歷、判斷、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03
  • 基于C語言實(shí)現(xiàn)隨機(jī)點(diǎn)名器(附源碼)

    基于C語言實(shí)現(xiàn)隨機(jī)點(diǎn)名器(附源碼)

    這篇文章主要為大家詳細(xì)介紹如何基于C語言實(shí)現(xiàn)一個(gè)簡單的隨機(jī)點(diǎn)名器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起動手嘗試一下
    2022-07-07
  • C/C++模擬實(shí)現(xiàn)煙花效果的示例代碼

    C/C++模擬實(shí)現(xiàn)煙花效果的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C/C++模擬實(shí)現(xiàn)煙花效果的兩種簡單方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解下
    2024-01-01
  • C語言帶你學(xué)會位段相關(guān)知識

    C語言帶你學(xué)會位段相關(guān)知識

    這篇文章主要介紹了什么是位段,位段的聲明和結(jié)構(gòu)是類似的,位段的成員必須是 int、unsigned int 或signed int;位段的成員名后邊有一個(gè)冒號和一個(gè)數(shù)字,本文有詳細(xì)的代碼案例,感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列(面試官的小結(jié))

    C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列(面試官的小結(jié))

    這篇文章主要給大家介紹了關(guān)于C++用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的相關(guān)資料,這是來自一名面試官的小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 淺談C++基類的析構(gòu)函數(shù)為虛函數(shù)

    淺談C++基類的析構(gòu)函數(shù)為虛函數(shù)

    本文重點(diǎn):應(yīng)該為多態(tài)基類聲明虛析構(gòu)器。一旦一個(gè)類包含虛函數(shù),它就應(yīng)該包含一個(gè)虛析構(gòu)器。如果一個(gè)類不用作基類或者不需具有多態(tài)性,便不應(yīng)該為它聲明虛析構(gòu)器。
    2015-10-10
  • OpenGL實(shí)現(xiàn)鼠標(biāo)移動方塊

    OpenGL實(shí)現(xiàn)鼠標(biāo)移動方塊

    這篇文章主要為大家詳細(xì)介紹了OpenGL實(shí)現(xiàn)鼠標(biāo)移動方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08

最新評論

武清区| 沈丘县| 营口市| 北宁市| 徐州市| 长汀县| 茂名市| 临沂市| 包头市| 秦安县| 乌什县| 容城县| 敦煌市| 天等县| 巴彦县| 建水县| 宜昌市| 佛学| 监利县| 沙河市| 阆中市| 铜陵市| 荥阳市| 清原| 金川县| 抚远县| 会东县| 巨鹿县| 炉霍县| 育儿| 庐江县| 松潘县| 买车| 灌云县| 惠东县| 巴里| 永安市| 崇信县| 密云县| 北宁市| 金门县|