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

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

在上一篇我們了解C語言中的函數(shù)及函數(shù)指針 景图, 使用函數(shù)指針 , 模擬了網(wǎng)絡(luò)請求的回調(diào)方式 , 今天我們來學(xué)習(xí)動態(tài)內(nèi)存分配骨坑。

我們在使用java的時候 锥咸, 所有的內(nèi)存都交由JVM做處理 狭瞎, 我們無法直接控制 , 雖然很少導(dǎo)致內(nèi)存溢出 搏予, 但是程序占用內(nèi)存卻會越來越大 熊锭, 所以我們在使用Android手機的時候 , 剛開始很流暢 雪侥, 用著用著就非惩胍螅卡 , 在打開大文件或是播放gif的時候 速缨, 如果采用java編寫處理引擎 锌妻, 則會比較卡 , 因為開辟的內(nèi)存空間無法控制 旬牲, GC回收又不是即時的 仿粹, 這時候就需要我們使用JNI技術(shù) , 使用C語言進行處理 原茅。接下來 吭历,我們就來學(xué)習(xí)C語言中的動態(tài)內(nèi)存分配 。

C語言中內(nèi)存的大致分配:

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

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

void* __cdecl malloc(
    _In_ _CRT_GUARDOVERFLOW size_t _Size
    );

使用如下:

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

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

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


void main() {

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

    getchar();

}

打開任務(wù)管理器 , 我們可以看到我們共存所占內(nèi)存 圆米, 正在以40M每秒的速度 卒暂, 蹭蹭的往上漲 , 以前的蠕蟲病毒就是如此 娄帖, 不斷的消耗內(nèi)存 也祠, 然后導(dǎo)致系統(tǒng)崩潰 。

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

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

使用如下:

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

下面我們來應(yīng)用一下:

void main() {

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

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

    // 在原有內(nèi)存上面蛮瞄,重新分配內(nèi)存大小
    printf("請輸入增加的內(nèi)存大小");
    int add;
    scanf("%d", &add);
    // 重新申請內(nèi)存大小 所坯, 傳入申請的內(nèi)存指針 谆扎, 申請內(nèi)存總大小
    int* p2 = (int*)realloc(p, (len + add) * sizeof(int));
    // 給新申請的內(nèi)存空間賦值
    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)內(nèi)存
    if (p2 != NULL)
    {
        free(p2);
        p2 = NULL;
    }
        
    system("pause");
}

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

內(nèi)存分配的幾個注意細(xì)節(jié):
1.不能多次釋放
2.釋放完之后 训桶, 給指針置NULL累驮,標(biāo)志釋放完成
3.內(nèi)存泄漏 (p重新賦值之后 , 再free 舵揭, 并沒有真正釋放 谤专, 要在賦值之前釋放前一個內(nèi)存空間)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市午绳,隨后出現(xiàn)的幾起案子置侍,更是在濱河造成了極大的恐慌,老刑警劉巖拦焚,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜡坊,死亡現(xiàn)場離奇詭異,居然都是意外死亡赎败,警方通過查閱死者的電腦和手機秕衙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灾梦,“玉大人,你說我怎么就攤上這事妓笙。” “怎么了萧福?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我蹂空,道長,這世上最難降的妖魔是什么悟民? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任篷就,我火速辦了婚禮射亏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己智润,他們只是感情好及舍,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布窟绷。 她就那樣靜靜地躺著,像睡著了一般兼蜈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上为狸,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天钥平,我揣著相機與錄音实撒,去河邊找鬼涉瘾。 笑死,一個胖子當(dāng)著我的面吹牛立叛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播其做,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼赁还,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了艘策?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤罚渐,失蹤者是張志新(化名)和其女友劉穎驯妄,沒想到半個月后荷并,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體青扔,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡源织,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片励两。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡当悔,死狀恐怖傅瞻,靈堂內(nèi)的尸體忽然破棺而出盲憎,到底是詐尸還是另有隱情,我是刑警寧澤饼疙,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布窑眯,位于F島的核電站屏积,受9級特大地震影響磅甩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渣聚,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一僧叉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瓶堕,春花似錦、人聲如沸捞烟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苍息。三九已至壹置,卻和暖如春表谊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爆办。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留余佃,地道東北人跨算。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像诸蚕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子背犯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容

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