欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解C語(yǔ)言中動(dòng)態(tài)內(nèi)存管理及柔性數(shù)組的使用

 更新時(shí)間:2022年07月18日 08:40:03   作者:蔣靈瑜的流水賬  
這篇文章主要為大家詳細(xì)介紹一下C語(yǔ)言中動(dòng)態(tài)內(nèi)存管理以及柔性數(shù)組的使用方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定的幫助,需要的可以參考一下

一、malloc

這個(gè)函數(shù)向堆區(qū)申請(qǐng)一塊連續(xù)的空間,并返回這塊內(nèi)存的地址。

int main()
{
    int* p = (int*)malloc(40);
    if (p == NULL)
    {
        printf("%s\n", strerror(errno));
        return 1;
    }
    free(p);
    p = NULL;
    return 0;
}

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

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

二、free

free函數(shù)用來(lái)釋放動(dòng)態(tài)開(kāi)辟的內(nèi)存。free的指針必須是指向動(dòng)態(tài)內(nèi)存空間的起始地址。

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

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

三、calloc

num:要?jiǎng)討B(tài)開(kāi)辟的元素個(gè)數(shù)

size:每個(gè)元素的大小

calloc=malloc+memset

calloc和malloc的區(qū)別就在于calloc會(huì)將動(dòng)態(tài)內(nèi)存開(kāi)辟的空間全部初始化為0

四、realloc

ptr:需要擴(kuò)容的原始地址

size:擴(kuò)容后的總大小

1、realloc在擴(kuò)容時(shí)的情況

1、擴(kuò)容時(shí)后方空間足夠,將在后方繼續(xù)擴(kuò)容,返回原始地址

2、擴(kuò)容時(shí)后方空間已被使用,將在新的一塊區(qū)域進(jìn)行擴(kuò)容,并將原始數(shù)據(jù)拷貝至新的區(qū)域,free原始地址指向的內(nèi)存,并返回內(nèi)存塊的地址。

3、空間不足,無(wú)法擴(kuò)容,返回空指針

2、realloc也能實(shí)現(xiàn)malloc功能

int main()
{
    int* p = (int*)realloc(NULL, 40);
    return 0;
}

realloc在當(dāng)malloc使用時(shí),第一個(gè)參數(shù)傳空指針即可。

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

1、free空指針

void text()
{
    int* p = (int*)realloc(NULL, 40);
    if (p == NULL)//判斷p是否為空指針
    {
        return;
    }
    *p = 20;
}

如果開(kāi)辟空間后,沒(méi)有判斷指針p是否是空指針,如果動(dòng)態(tài)內(nèi)存開(kāi)辟失敗,那么*p將會(huì)解引用空指針。

2、對(duì)動(dòng)態(tài)開(kāi)辟的空間越界訪問(wèn)

void text()
{
    int* p = (int*)realloc(NULL, 40);
    int* m = p;
    if (p == NULL)
    {
        return;
    }
    for (int i = 0; i <= 10; i++)
    {
        p[i] = i;//越界
        p++;
    }
}

3、對(duì)非動(dòng)態(tài)開(kāi)辟內(nèi)容free

void text()
{
    int arr[] = {1,2,3};
    int* p = arr;
    free(p);//不能對(duì)非動(dòng)態(tài)開(kāi)辟的空間進(jìn)行free
}

4、只free動(dòng)態(tài)開(kāi)辟空間的一部分

void text()
{
    int* p = (int*)malloc(40);
    p++;
    free(p);//p不再指向動(dòng)態(tài)開(kāi)辟空間的起始位置
}

實(shí)際寫(xiě)代碼的時(shí)候還是得多注意這種情況,指針p在使用的過(guò)程中已經(jīng)不再是初始位置,free(p)會(huì)崩潰。

5、對(duì)同一塊內(nèi)存多次free

void text()
{
    int* p = (int*)realloc(NULL, 40);
    free(p);
    //p = NULL;
 
    free(p);
}

free(p)后及時(shí)將p置為空指針,哪怕p被多次free也沒(méi)問(wèn)題。

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

void text()
{
    int* p = (int*)realloc(NULL, 40);
    int a = 0;
    scanf("%d", &a);
    if (a == 5)
        return;
    free(p);
    p = NULL;
}

當(dāng)函數(shù)提前終止,沒(méi)有機(jī)會(huì)走到free,可能會(huì)造成內(nèi)存泄漏

另一種可能是調(diào)用了動(dòng)態(tài)開(kāi)辟內(nèi)存的函數(shù),使用者未在外部進(jìn)行free

六、柔性數(shù)組

1、柔性數(shù)組的概念

C99中,結(jié)構(gòu)體中最后一個(gè)成員變量可以是未知大小的數(shù)組

struct S
{
    int a;
    int arr[0];//這里的arr[0]代表未知大小的數(shù)組
};
//或者如下寫(xiě)法:
struct S
{
    int a;
    int arr[];
};

2、柔性數(shù)組的特點(diǎn)

結(jié)構(gòu)體中的柔性數(shù)組成員前面必須至少一個(gè)其他成員。

sizeof 返回的這種結(jié)構(gòu)大小不包括柔性數(shù)組的內(nèi)存。

包含柔性數(shù)組成員的結(jié)構(gòu)用malloc ()函數(shù)進(jìn)行內(nèi)存的動(dòng)態(tài)分配,并且分配的內(nèi)存應(yīng)該大于結(jié)構(gòu)的大小,以適應(yīng)柔性數(shù)組的預(yù)期大小。

3、柔性數(shù)組的使用場(chǎng)景

場(chǎng)景:將結(jié)構(gòu)體中所有的成員變量全部在堆區(qū)開(kāi)辟

使用柔性數(shù)組:

struct S
{
    int a;
    int arr[0];
};
int main()
{
    struct S s;
    struct S* ps = &s;
    ps = (struct S*)realloc(NULL,sizeof(s) + 40);//首次開(kāi)辟空間,傳NULL
    if (ps == NULL)
    {
        exit(-1);
    }
    free(ps);
    ps = NULL;
    return 0;
}

注意此處的realloc第一個(gè)參數(shù)傳入的是NULL而不是&s,傳入&s會(huì)崩潰,是因?yàn)檫@是第一次動(dòng)態(tài)內(nèi)存開(kāi)辟,此處傳入NULL相當(dāng)于使用malloc

完成開(kāi)辟后s在內(nèi)存中的存儲(chǔ)如下圖:

使用常規(guī)結(jié)構(gòu)體:

struct S
{
    int a;
    int* parr;
};
int main()
{
    struct S* p = (struct S*)malloc(sizeof(struct S));//對(duì)結(jié)構(gòu)體動(dòng)態(tài)開(kāi)辟空間
    if (p == NULL)
    {
        exit(-1);
    }
    int* tmp= (int*)malloc(sizeof(int) * 2);//在堆區(qū)動(dòng)態(tài)開(kāi)辟一塊空間
    if (tmp == NULL)
    {
        exit(-1);
    }
    p->parr = tmp;
    free(p->parr);//釋放時(shí),需要先釋放p->parr指向的空間
    p->parr = NULL;
    free(p);//再將結(jié)構(gòu)體指針p指向的空間釋放
    p = NULL;
    return 0;
}

完成開(kāi)辟后s在內(nèi)存中的存儲(chǔ)如下圖:

4、柔性數(shù)組的優(yōu)點(diǎn)

1、在上述條件下,使用柔性數(shù)組方便動(dòng)態(tài)內(nèi)存釋放。如果我們的代碼是在一個(gè)給別人用的函數(shù)中,你在里面做了二次內(nèi)存分配,并把整個(gè)結(jié)構(gòu)體返回給用戶。用戶調(diào)用free可以釋放結(jié)構(gòu)體,但是用戶并不知道這個(gè)結(jié)構(gòu)體內(nèi)的成員也需要free,可能會(huì)造成內(nèi)存泄漏。所以,如果我們把結(jié)構(gòu)體的內(nèi)存以及其成員要的內(nèi)存一次性分配好了,并返回給用戶一個(gè)結(jié)構(gòu)體指針,用戶做一次free就可以把所有的內(nèi)存給釋放掉。

2、連續(xù)的內(nèi)存有益于提高訪問(wèn)速度,也有益于減少內(nèi)存碎片。

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

相關(guān)文章

  • C++實(shí)現(xiàn)支持泛型的LFU詳解

    C++實(shí)現(xiàn)支持泛型的LFU詳解

    這篇文章主要給大家介紹了關(guān)于C++實(shí)現(xiàn)LFU的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • C++模擬實(shí)現(xiàn)STL容器vector的示例代碼

    C++模擬實(shí)現(xiàn)STL容器vector的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器vector的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2022-11-11
  • C++實(shí)現(xiàn)對(duì)RGB圖片進(jìn)行編碼的示例代碼

    C++實(shí)現(xiàn)對(duì)RGB圖片進(jìn)行編碼的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用得到的RGB信息重新對(duì)RGB圖片進(jìn)行編碼,以及對(duì)其他圖片如BMP所得到的RGB信息進(jìn)行編碼從而得到*.jpg文件,感興趣的可以了解一下
    2023-05-05
  • C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解

    C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解

    今天小編就為大家分享一篇關(guān)于C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2021-09-09
  • C++ POSIX API超詳細(xì)分析

    C++ POSIX API超詳細(xì)分析

    這篇文章主要介紹了C++ POSIXAPI的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)合并字符串

    C語(yǔ)言實(shí)現(xiàn)合并字符串

    今天小編就為大家分享一篇C語(yǔ)言實(shí)現(xiàn)合并字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • C++實(shí)現(xiàn)String與UF8互轉(zhuǎn)

    C++實(shí)現(xiàn)String與UF8互轉(zhuǎn)

    這篇文章介紹了C++實(shí)現(xiàn)String與UF8互轉(zhuǎn)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法時(shí)間空間復(fù)雜度基礎(chǔ)實(shí)踐

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法時(shí)間空間復(fù)雜度基礎(chǔ)實(shí)踐

    這篇文章主要為大家介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法中時(shí)間空間復(fù)雜度的基礎(chǔ)實(shí)踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • C++ 中const和復(fù)合類型

    C++ 中const和復(fù)合類型

    本文給大家講述的是C++ 中比較難理解的const和復(fù)合類型,結(jié)合自己的一些經(jīng)驗(yàn),分享給大家,希望大家能夠喜歡。
    2016-02-02
  • C++靜態(tài)變量,常量的存儲(chǔ)位置你真的了解嗎

    C++靜態(tài)變量,常量的存儲(chǔ)位置你真的了解嗎

    這篇文章主要介紹了C++中靜態(tài)變量與常量的存儲(chǔ)位置的相關(guān)資料,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-08-08

最新評(píng)論