天天看點

9、動态記憶體配置設定

存儲區劃分

記憶體管理:軟體運作時對計算機記憶體資源的配置設定和使用的技術,其最主要的目的是高效、快速的配置設定、并在适當的時候釋放和回收資源

記憶體配置設定方式

  • 從靜态存儲區域配置設定:記憶體在程式編譯時已經配置設定好,這塊記憶體在程式的整個運作期間都存在。例如:全局變量、static變量
  • 在棧上建立,在執行函數時,函數内局部變量的存儲單元都可以在棧上建立,,函數執行結束後這些存儲單元你自動被釋放。棧記憶體配置設定運算内置于處理器的指令中,效率高,但能夠配置設定的記憶體容量有限
  • 從堆上配置設定(動态記憶體配置設定),程式運作時用malloc或new申請任意多少的記憶體,程式員自己負責在何時用free或delete釋放記憶體,動态記憶體的生存周期由程式員決定,使用靈活,但有許多缺點
9、動态記憶體配置設定

靜态記憶體配置設定(BSS段、資料段)

BSS段(Block Started by Symbol):

用來存放程式中未初始化的全局變量和靜态變量,它不包含任何資料,隻是簡單地維護開始和結束的位址,即總大小,以便記憶體區能在運作時配置設定并有效地清零。BSS不占用磁盤空間,隻在運作時占用。

資料段(data segment)

用來存放已初始化的全局變量和靜态變量的一塊記憶體區域,可以分為隻讀資料段和讀寫資料段,字元串常量等,但一般都放在隻讀資料段中

棧記憶體

用來存放程式臨時建立的局部變量

9、動态記憶體配置設定

棧記憶體的錯誤使用

char *fun()
{
     //注意此處是把常量區的字元串“iphone”拷貝到棧記憶體中。
     char string[] = "iphone";
     return string;  //棧記憶體傳回是不安全的,禁⽌!!!
}
           

常量區

//'a' 字元常量
//5 整形常量
//"iPhone" 字元串常量
//常量占⽤記憶體,隻讀狀态,決不可修改!
char * string = "iPhone";
string[] = 'a'; //運⾏崩潰!
           

靜态存儲區

  • 隻初始化一次
  • 如果初始沒給值,預設值為0
  • 隻有程式退出才釋放
  • 将變量定義的類型前加static,則該變量存儲存儲在靜态存儲區

堆區

malloc等記憶體配置設定函數配置設定的記憶體,手動配置設定,手動釋放

代碼區

用于存放程式執行代碼的一段區域,所有的語句編譯後會生成CPU指令存儲在代碼區

堆記憶體配置設定函數

動态記憶體配置設定

9、動态記憶體配置設定
void * malloc(unsigned size);//從記憶體的堆區配置設定大小為size個位元組的連續記憶體空間
//如果記憶體配置設定成功,傳回記憶體的首位址;失敗則傳回NULL
           
//從記憶體中申請一塊空間,可以存儲4個int類型的資料即共16個位元組
    //指派要求=兩邊的類型要一緻,是以要進行一個強制轉換,由預設的void * 轉換為int *
    int *p = (int *) malloc(*sizeof(int));  //16個位元組
    //使用一個函數給malloc申請的空間進行初始化
    memset(p, 'A', );//中間的參數讀的是ASCII碼值,是以寫0還是會出現奇怪的數,是以最好直接寫一個字元
    if (p != NULL) {
        //申請成功要做的事
        //p中存放的是新申請的記憶體空間的首位址
        *p = ;
        *(p+) = ;
        *(p+) = ;
        *(p+) = ;//存放4個整數
        //如果配置設定的空間未指派,那麼初始值會是垃圾數,不一定為0
    }else{
        printf("記憶體申請失敗!\n");
    }
    for (int i = ; i < ; i++) {
        printf("%c\t",*(p+i));//循環結束後,p就不再指向剛才的首位址,而是指向其他未知空間,此時,就不要用p再進行其他操作了
    }
           

記憶體釋放

其他記憶體配置設定函數

calloc

配置設定n個size大小的空間,并且把該記憶體上的所有位元組清零

void * calloc(unsigned n,unsigned size);
           
//calloc函數
    //格式:calloc(塊數,長度)即配置設定塊數個長度的記憶體空間
    //可以自動初始化為0,不需要memset了
    int *p = (int *)calloc(,sizeof(int));
    if (p != NULL) {
        //申請成功要做的事
        //p中存放的是新申請的記憶體空間的首位址
        *p = ;
        *(p+) = ;
        *(p+) = ;
        *(p+) = ;//存放4個整數
        //如果配置設定的空間未指派,那麼初始值會是垃圾數,不一定為0
    }else{
        printf("記憶體申請失敗!\n");
    }

    for (int i = ; i < ; i++) {
        printf("%d\t",*(p+i));//循環結束後,p就不再指向剛才的首位址,而是指向其他未知空間,此時,就不要用p再進行其他操作了
    }
           

realloc

按給定的位址以及給定的大小重新配置設定

void *realloc(void *p,unsigned newSize);
           
//realloc函數:按給定的位址以及給定的大小給已經存在的空間進行擴充
    //格式:realloc(位址,新長度)
    int *p = (int *)calloc(,sizeof(int));
    p = (int *)realloc(p,*sizeof(int));//為了配置設定連續的空間,若目前空間不夠,則會找新的足夠大的空間,傳回新的位址

    if (p != NULL) {
        //申請成功要做的事
        //p中存放的是新申請的記憶體空間的首位址
        *p = ;
        *(p+) = ;
        *(p+) = ;
        *(p+) = ;//存放4個整數
        //如果配置設定的空間未指派,那麼初始值會是垃圾數,不一定為0
    }else{
        printf("記憶體申請失敗!\n");
    }

    for (int i = ; i < ; i++) {
        printf("%d\t",*(p+i));//循環結束後,p就不再指向剛才的首位址,而是指向其他未知空間,此時,就不要用p再進行其他操作了
    }
           

記憶體操作函數

初始化記憶體

記憶體拷貝

記憶體比較

int memcmp(const void *buf1, const void  *buf2, unsigned int count)
//⽐較buf1和buf2指向的記憶體是否相同,⽐較count個位元組
           

繼續閱讀