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

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

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

一、malloc

這個函數(shù)向堆區(qū)申請一塊連續(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;
}

如果開辟失敗,則返回一個NULL指針,因此malloc的返回值一定要做檢查。

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

二、free

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

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

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

三、calloc

num:要動態(tài)開辟的元素個數(shù)

size:每個元素的大小

calloc=malloc+memset

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

四、realloc

ptr:需要擴容的原始地址

size:擴容后的總大小

1、realloc在擴容時的情況

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

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

3、空間不足,無法擴容,返回空指針

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

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

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

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

1、free空指針

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

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

2、對動態(tài)開辟的空間越界訪問

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、對非動態(tài)開辟內(nèi)容free

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

4、只free動態(tài)開辟空間的一部分

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

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

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

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

free(p)后及時將p置為空指針,哪怕p被多次free也沒問題。

6、動態(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;
}

當函數(shù)提前終止,沒有機會走到free,可能會造成內(nèi)存泄漏

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

六、柔性數(shù)組

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

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

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

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

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

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

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

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

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

使用柔性數(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);//首次開辟空間,傳NULL
    if (ps == NULL)
    {
        exit(-1);
    }
    free(ps);
    ps = NULL;
    return 0;
}

注意此處的realloc第一個參數(shù)傳入的是NULL而不是&s,傳入&s會崩潰,是因為這是第一次動態(tài)內(nèi)存開辟,此處傳入NULL相當于使用malloc

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

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

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

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

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

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

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

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

相關(guān)文章

  • 使用c++實現(xiàn)OpenCV繪制旋轉(zhuǎn)矩形圖形

    使用c++實現(xiàn)OpenCV繪制旋轉(zhuǎn)矩形圖形

    這篇文章主要給大家介紹了使用c++實現(xiàn)OpenCV繪制圖形旋轉(zhuǎn)矩形的方法案例,通過圖文及代碼形式進行了詳細的描述,有需要的朋友可以參考下,希望可以有所幫助
    2021-08-08
  • C++虛函數(shù)表的原理與使用解析

    C++虛函數(shù)表的原理與使用解析

    對C++?了解的人都應(yīng)該知道虛函數(shù)(Virtual?Function)是通過一張?zhí)摵瘮?shù)表(Virtual?Table)來實現(xiàn)的。簡稱為V-Table。本文就將詳細講講虛函數(shù)表的原理與使用,需要的可以參考一下
    2022-04-04
  • C++17中的std::from_chars函數(shù)使用及說明

    C++17中的std::from_chars函數(shù)使用及說明

    這篇文章主要介紹了C++17中的std::from_chars函數(shù)使用及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-10-10
  • C++設(shè)計模式之中介者模式

    C++設(shè)計模式之中介者模式

    這篇文章主要介紹了C++設(shè)計模式之中介者模式,本文講解了什么是中介者模式、中介者模式的使用場合、中介者模式的優(yōu)缺點等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • C語言中volatile關(guān)鍵字的作用及說明

    C語言中volatile關(guān)鍵字的作用及說明

    文中主要介紹了C語言中volatile關(guān)鍵字的含義和使用場景,volatile是一個類型修飾符,主要用來修飾被不同線程訪問和修改的變量,它的作用是防止編譯器對代碼進行優(yōu)化,確保每次直接讀取原始內(nèi)存地址的值
    2024-10-10
  • C++實現(xiàn)LeetCode(27.移除元素)

    C++實現(xiàn)LeetCode(27.移除元素)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(27.移除元素),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • visual studio 建立dll類型工程、控制臺程序

    visual studio 建立dll類型工程、控制臺程序

    這篇文章主要介紹了visual studio 建立dll、控制臺類型工程的相關(guān)知識,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • 構(gòu)造函數(shù)定義為private或者protected的好處

    構(gòu)造函數(shù)定義為private或者protected的好處

    從語法上來講,一個函數(shù)被聲明為protected或者private,那么這個函數(shù)就不能從“外部”直接被調(diào)用了。對于protected的函數(shù),子類的“內(nèi)部”的其他函數(shù)可以調(diào)用之。而對于private的函數(shù),只能被本類“內(nèi)部”的其他函數(shù)說調(diào)用
    2013-10-10
  • C/C++ 運用Npcap發(fā)送UDP數(shù)據(jù)包的完美過程

    C/C++ 運用Npcap發(fā)送UDP數(shù)據(jù)包的完美過程

    UDP 是一種無連接、輕量級的傳輸層協(xié)議,與 TCP 相比,它不提供可靠性、流控制和錯誤恢復(fù)機制,但卻更加簡單且具有較低的開銷,這篇文章主要介紹了C/C++ 運用Npcap發(fā)送UDP數(shù)據(jù)包,需要的朋友可以參考下
    2023-11-11
  • C++實現(xiàn)KFC點餐系統(tǒng)

    C++實現(xiàn)KFC點餐系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)KFC點餐系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07

最新評論

吉水县| 宜黄县| 壤塘县| 义马市| 青浦区| 博爱县| 噶尔县| 嘉义市| 华池县| 宜州市| 浦北县| 宁都县| 锡林郭勒盟| 辽阳县| 辽阳市| 宝鸡市| 自治县| 金溪县| 安徽省| 庆元县| 罗城| 遵义市| 岑溪市| 新建县| 双城市| 台北市| 安陆市| 张家口市| 色达县| 准格尔旗| 澄城县| 温州市| 宁陕县| 盘山县| 博罗县| 家居| 东山县| 定边县| 侯马市| 汶上县| 德钦县|