亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

淺談c語(yǔ)言中的堆

原創(chuàng) 2016-11-10 09:38:28 718
摘要:操作系統(tǒng)堆管理器管理:堆管理器是操作系統(tǒng)的一個(gè)模塊,堆管理內(nèi)存分配靈活,按需分配。 大塊內(nèi)存:  堆內(nèi)存管理者總量很大的操作系統(tǒng)內(nèi)存塊,各進(jìn)程可以按需申請(qǐng)使用,使用完釋放。 程序手動(dòng)申請(qǐng)&釋放:  手工意思是需要寫(xiě)代碼去申請(qǐng)malloc和釋放free。 臟內(nèi)存:  堆內(nèi)存也是反復(fù)使用的,而且使用者用完釋放前不會(huì)清除,因此也是臟的。 臨時(shí)性:  堆內(nèi)存

操作系統(tǒng)堆管理器管理:

堆管理器是操作系統(tǒng)的一個(gè)模塊,堆管理內(nèi)存分配靈活,按需分配。
 大塊內(nèi)存:

  堆內(nèi)存管理者總量很大的操作系統(tǒng)內(nèi)存塊,各進(jìn)程可以按需申請(qǐng)使用,使用完釋放。
 程序手動(dòng)申請(qǐng)&釋放:

  手工意思是需要寫(xiě)代碼去申請(qǐng)malloc和釋放free。
 臟內(nèi)存:

  堆內(nèi)存也是反復(fù)使用的,而且使用者用完釋放前不會(huì)清除,因此也是臟的。
 臨時(shí)性:

  堆內(nèi)存只在malloc和free之間屬于我這個(gè)進(jìn)程,而可以訪問(wèn)。在malloc之前和free之后
      都不能再訪問(wèn),否則會(huì)有不可預(yù)料的后果。

堆內(nèi)存使用范例

(1)void *是個(gè)指針類(lèi)型,malloc返回的是一個(gè)void *類(lèi)型的指針,實(shí)質(zhì)上malloc返回的是堆管理器分配給我本次申請(qǐng)的那段內(nèi)存空間的首地址(malloc返回的值其實(shí)是一個(gè)數(shù)字,這個(gè)數(shù)字表示一個(gè)內(nèi)存地址)。為什么要使用void *作為類(lèi)型?主要原因是malloc幫我們分配內(nèi)存時(shí)只是分配了內(nèi)存空間,至于這段空間將來(lái)用來(lái)存儲(chǔ)什么類(lèi)型的元素malloc是不關(guān)心的,由我們程序自己來(lái)決定。

(2)什么是void類(lèi)型。void類(lèi)型不表示沒(méi)有類(lèi)型,而表示萬(wàn)能類(lèi)型。void的意思就是說(shuō)這個(gè)數(shù)據(jù)的類(lèi)型當(dāng)前是不確定的,在需要的時(shí)候可以再去指定它的具體類(lèi)型。void *類(lèi)型是一個(gè)指針類(lèi)型,這個(gè)指針本身占4個(gè)字節(jié),但是指針指向的類(lèi)型是不確定的,換句話說(shuō)這個(gè)指針在需要的時(shí)候可以被強(qiáng)制轉(zhuǎn)化成其他任何一種確定類(lèi)型的指針,也就是說(shuō)這個(gè)指針可以指向任何類(lèi)型的元素。

(3)malloc的返回值:成功申請(qǐng)空間后返回這個(gè)內(nèi)存空間的指針,申請(qǐng)失敗時(shí)返回NULL。所以malloc獲取的內(nèi)存指針使用前一定要先檢驗(yàn)是否為NULL。

(4)malloc申請(qǐng)的內(nèi)存時(shí)用完后要free釋放。free(p);會(huì)告訴堆管理器這段內(nèi)存我用完了你可以回收了。堆管理器回收了這段內(nèi)存后這段內(nèi)存當(dāng)前進(jìn)程就不應(yīng)該再使用了。因?yàn)獒尫藕蠖压芾砥骶涂赡馨堰@段內(nèi)存再次分配給別的進(jìn)程,所以你就不能再使用了。

(5)再調(diào)用free歸還這段內(nèi)存之前,指向這段內(nèi)存的指針p一定不能丟(也就是不能給p另外賦值)。因?yàn)閜一旦丟失這段malloc來(lái)的內(nèi)存就永遠(yuǎn)的丟失了(內(nèi)存泄漏),直到當(dāng)前程序結(jié)束時(shí)操作系統(tǒng)才會(huì)回收這段內(nèi)存。

(6) malloc(0) malloc申請(qǐng)0字節(jié)內(nèi)存本身就是一件無(wú)厘頭事情,一般不會(huì)碰到這個(gè)需要。 如果真的malloc(0)返回的是NULL還是一個(gè)有效指針?答案是:實(shí)際分配了16Byte的一段內(nèi)存并且返回了這段內(nèi)存的地址。這個(gè)答案不是確定的,因?yàn)镃語(yǔ)言并沒(méi)有明確規(guī)定malloc(0)時(shí)的表現(xiàn),由各malloc函數(shù)庫(kù)的實(shí)現(xiàn)者來(lái)定義。

   malloc(4) gcc中的malloc默認(rèn)最小是以16B為分配單位的。如果malloc小于16B的大小時(shí)都會(huì)返回一個(gè)16字節(jié)的大小的內(nèi)存。malloc實(shí)現(xiàn)時(shí)沒(méi)有實(shí)現(xiàn)任意自己的分配而是允許一些大小的塊內(nèi)存的分配。    malloc(20)去訪問(wèn)第25、第250、第2500····會(huì)怎么樣 實(shí)戰(zhàn)中:120字節(jié)處正確,1200字節(jié)處正確····終于繼續(xù)往后訪問(wèn)總有一個(gè)數(shù)字處開(kāi)始段錯(cuò)誤了。

#include <stdio.h>
#include <stdlib.h>
 
 
int main(void)
{
    int *p = (int *)malloc(20);
    // 第二步:檢驗(yàn)分配是否成功
    if (NULL == p)
    {
        printf("malloc error.\n");
        return -1;
    }
    
    *(p+3) = 12;
    *(p+300000) = 1234;
    printf("*(p+3) = %d.\n", *(p+3));
    printf("*(p+300000) = %d.\n", *(p+300000));        
    


/*
    int *p1 = (int *)malloc(4);        // p2-p1 = 0x10 = 16Byte
    int *p2 = (int *)malloc(4);

    printf("p1 = %p.\n", p1);        // p2-p1 = 0x10 = 16Byte
    printf("p2 = %p.\n", p2);
*/
    
/*
    int *p1 = (int *)malloc(0);
    int *p2 = (int *)malloc(0);

    printf("p1 = %p.\n", p1);        // p2-p1 = 0x10 = 16Byte
    printf("p2 = %p.\n", p2);
    */
/*
    // 需要一個(gè)1000個(gè)int類(lèi)型元素的數(shù)組
    
    // 第一步:申請(qǐng)和綁定
    int *p = (int *)malloc(1000*sizeof(int));
    // 第二步:檢驗(yàn)分配是否成功
    if (NULL == p)
    {
        printf("malloc error.\n");
        return -1;
    }
    
    // 第三步:使用申請(qǐng)到的內(nèi)存
    //p = NULL;
    //p = &a;    // 如果在free之前給p另外賦值,那么malloc申請(qǐng)的那段內(nèi)存就丟失掉了
                // malloc后p和返回的內(nèi)存相綁定,p是那段內(nèi)存在當(dāng)前進(jìn)程的唯一聯(lián)系人
                // 如果p沒(méi)有free之前就丟了,那么這段內(nèi)存就永遠(yuǎn)丟了。丟了的概念就是
                // 在操作系統(tǒng)的堆管理器中這段內(nèi)存是當(dāng)前進(jìn)程拿著的,但是你也用不了
                // 所以你想申請(qǐng)新的內(nèi)存來(lái)替換使用,這就叫程序“吃內(nèi)存”,學(xué)名叫內(nèi)存泄漏
    *(p+0) = 1;
    *(p+1) = 2;
    printf("*(p+0) = %d.\n", *(p+0));
    printf("*(p+1) = %d.\n", *(p+1));                
                    
    *(p+222) = 133;
    *(p+223) = 222;                
                    
    
    // 第四步:釋放
    free(p);
    p = NULL;
    
    printf("*(p+222) = %d.\n", *(p+222));
    printf("*(p+223) = %d.\n", *(p+223));
*/
    return 0;
}


發(fā)佈手記

熱門(mén)詞條