C語言基礎及指針⑤動態(tài)內存分配

接續(xù)上篇C語言基礎及指針④函數(shù)指針

在上一篇我們了解C語言中的函數(shù)及函數(shù)指針 , 使用函數(shù)指針 , 模擬了網(wǎng)絡請求的回調方式 , 今天我們來學習動態(tài)內存分配。

我們在使用java的時候 , 所有的內存都交由JVM做處理 , 我們無法直接控制 , 雖然很少導致內存溢出 , 但是程序占用內存卻會越來越大 , 所以我們在使用Android手機的時候 , 剛開始很流暢 , 用著用著就非???, 在打開大文件或是播放gif的時候 , 如果采用java編寫處理引擎 , 則會比較卡 , 因為開辟的內存空間無法控制 , GC回收又不是即時的 , 這時候就需要我們使用JNI技術 , 使用C語言進行處理 。接下來 ,我們就來學習C語言中的動態(tài)內存分配 。

C語言中內存的大致分配:

內存 描述 特性
棧區(qū) 是一個確定的常數(shù)(win 1~2M) 不同平臺會有不同大小 超出會提示stackoverflow 自動分配 , 自動釋放
堆區(qū) 用于動態(tài)內存分配 手動分配和釋放 , 可占用80%內存
全局區(qū)或靜態(tài)區(qū) 在程序中明確被初始化的全局變量、靜態(tài)變量(包括全局靜態(tài)變量和局部靜態(tài)變量)和常量數(shù)據(jù)(如字符串常量) 只初始化一次
程序代碼區(qū) 代碼區(qū)指令根據(jù)程序設計流程依次執(zhí)行,對于順序指令,則只會執(zhí)行一次(每個進程),如果反復,則需要使用跳轉指令,如果進行遞歸,則需要借助棧來實現(xiàn)。 代碼區(qū)的指令中包括操作碼和要操作的對象(或對象地址引用)

C語言中動態(tài)分配內存是在堆區(qū) , java語言中new一個對象 , 也會在堆內存中開辟一塊空間 , 來存儲我們創(chuàng)建的這個對象 。在C語言中 , 我們在堆區(qū)開辟一塊空間使用的關鍵字是malloc , malloc函數(shù)定義:

void* __cdecl malloc(
    _In_ _CRT_GUARDOVERFLOW size_t _Size
    );

使用如下:

// 動態(tài)內存分配 , 使用malloc函數(shù)在對內存中開辟連續(xù)的內存空間 , 單位是:字節(jié)
// 申請一塊40M的堆內存
int* p = (int*)malloc(1024 *1024 * 10 * sizeof(int));

下面我們來模擬一下病毒:

/*動態(tài)內存分配*/
void heapFunc() {
    // 動態(tài)內存分配 , 使用malloc函數(shù)在對內存中開辟連續(xù)的內存空間 , 單位是:字節(jié)
    // 申請一塊40M的堆內存
    int* p = (int*)malloc(1024 *1024 * 10 * sizeof(int));
}


void main() {

    while (1)
    {
        // 睡一秒執(zhí)行一次
        Sleep(1000);
        heapFunc();
    }

    getchar();

}

打開任務管理器 , 我們可以看到我們共存所占內存 , 正在以40M每秒的速度 , 蹭蹭的往上漲 , 以前的蠕蟲病毒就是如此 , 不斷的消耗內存 , 然后導致系統(tǒng)崩潰 。

在使用靜態(tài)內存分配的時候 , 內存大小是固定的 , 很容易超出棧內存的最大值, 預估大小往往大大的超出使用大小 , 浪費內存 。使用malloc申請內存 , 最重要的一個點就是可以動態(tài)改變申請的內存大小 , 可以使用realloc函數(shù)來重新申請內存大小,realloc函數(shù)定義:

void* __cdecl realloc(
    _Pre_maybenull_ _Post_invalid_ void*  _Block,
    _In_ _CRT_GUARDOVERFLOW        size_t _Size
    );

使用如下:

// 重新申請內存大小 , 傳入申請的內存指針 , 申請內存總大小
int* p2 = realloc(p, (len + add) * sizeof(int));

下面我們來應用一下:

void main() {

    int len;
    printf("請輸入首次分配內存大?。?);
    scanf("%d", &len);
    // 動態(tài)分配內存 , 內存空間是連續(xù)的
    int* p = (int*)malloc(len * sizeof(int));
    // 給申請的內存空間賦值
    int i = 0;
    for (; i < len ; i++)
    {    // 生成隨機數(shù)賦值
        p[i] = rand() % 100;

        printf("array[%d] = %d , %#x\n", i, p[i], &p[i]);
    }

    // 在原有內存上面,重新分配內存大小
    printf("請輸入增加的內存大小");
    int add;
    scanf("%d", &add);
    // 重新申請內存大小 , 傳入申請的內存指針 , 申請內存總大小
    int* p2 = (int*)realloc(p, (len + add) * sizeof(int));
    // 給新申請的內存空間賦值
    int j = len;
    for (; j < len + add ; j++)
    {
        p2[j] = rand() % 200;
    
    }

    // 打印
    j = 0;
    for (; j < len + add; j++)
    {
        printf("array[%d] = %d , %#x\n", j, p2[j], &p2[j]);
    }
    
    // 回收申請的動態(tài)內存
    if (p2 != NULL)
    {
        free(p2);
        p2 = NULL;
    }
        
    system("pause");
}

使用mallocrealloc配合 , 就可以模擬出我們java中的集合類型,動態(tài)改變內存空間大小 。 使用malloc 第一次申請的內存首地址和第二次申請的內存首地址可能相同也可能不同 , 因為申請的內存是連續(xù)的 , 所有 , 但第一次申請的空間的后續(xù)空間不夠用時 , 會重新開辟新的空間 , 并將數(shù)據(jù)copy到新的空間里面 。

內存分配的幾個注意細節(jié):
1.不能多次釋放
2.釋放完之后 , 給指針置NULL,標志釋放完成
3.內存泄漏 (p重新賦值之后 , 再free , 并沒有真正釋放 , 要在賦值之前釋放前一個內存空間)

Android程序員學C系列:
C語言基礎及指針①
C語言基礎及指針②之指針內存分析
C語言基礎及指針③函數(shù)與二級指針
C語言基礎及指針④函數(shù)指針
C語言基礎及指針⑤動態(tài)內存分配
C語言基礎及指針⑥字符操作
C語言基礎及指針⑦結構體與指針
C語言基礎及指針⑧文件IO
C語言基礎及指針⑨聯(lián)合體與枚舉
C語言基礎及指針⑩預編譯及jni.h分析

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • C語言中內存分配 在任何程序設計環(huán)境及語言中,內存管理都十分重要。在目前的計算機系統(tǒng)或嵌入式系統(tǒng)中,內存資源仍然是...
    一生信仰閱讀 1,177評論 0 2
  • (JG-2014-08-20)(前半部分經(jīng)過網(wǎng)上多篇文章對比整理)(后半部分根據(jù)ExceptionalCpp、C+...
    JasonGao閱讀 5,614評論 2 23
  • 前言 C語言作為一門應用途廣泛、功能強大、使用靈活的面向過程式編程語言。既可用于編寫應用軟件,又能用于編寫系統(tǒng)軟件...
    老板娘來盤一血閱讀 13,008評論 32 83
  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數(shù)據(jù)結構; ...
    朱森閱讀 3,464評論 3 44
  • 此刻,很慶幸還有那么一小段獨處時間給自己,借由“寫點什么”跟自己對對話,我喜歡這樣的方式,并保持了很多年。 今天醒...
    作家阿紫閱讀 237評論 0 0