內存分配(Day-9)

計算機內存劃分爲5個區:棧區 堆區 靜態區 常量區 代碼區

1. 5大區:

  1. 棧區:
    1.1. 函數的參數或者是局部變量存儲在棧區
    1.2. 局部變量:在函數 分支 循環的{}中定義的變量
    1.3. 棧區內存的管理方式:由系統負責分配和回收
    1.4. 定義變量時分配,函數執行結束後系統回收
    1.5. 內存被系統回收後,原來存儲的數據沒有被清空,只是標記回收
    1.6. 棧區存儲的特點:先進後出 後進先出
    1.7. 入棧:定義變量在棧區分配存儲空間,出棧: 回收內存
    1.8. 棧頂:後放進去的數據在棧頂 棧底:棧區內存起始的位置
    |_______棧頂_________| 高
    |____________________| |
    |____________________| |
    |_______棧底_________| 低

  2. 常量區(文字常量區):
    2.1. 常量區的內存管理:由系統分配和回收(程序結束運行時被回收)
    2.2. 常量區的數據只能被讀取,不能被修改

  3. 全局變量:
    3.1. 使用關鍵字static修飾的變量 以及在函數外定義的變量(全局變量或者靜態變量)
    3.2. 靜態區的內存管理:由系統分配和回收(程序運行結束回收)
    3.3. 靜態區的變量只能初始化一次,在編譯時進行初始化
    3.4. 靜態區的變量沒有設置初始值時,默認值爲:0

  4. 代碼區:函數運行時存儲的區域
    4.1. 代碼區的內存管理機制:系統負責分配和回收
    4.2. 回收:程序運行結束後

  5. 堆區:
    5.1. 堆區的內存管理:開發人員負責分配與回收
    5.2. 回收:程序員自行回收
    5.3. void *malloc(size_t):

    指定分配的存儲空間的大小(字節數), 將分配的存儲空間的起始地址返回
    堆內存是使用地址操作,地址存儲在對應的指針變量中
    void *malloc(<#size_t#>)
    /*
    void *:無類型指針
    malloc = memory (內存) allocation(分配)
    size 表示分配多大的存儲空間,單位是字節
    */
    malloc返回的是地址,需要用指針獲取

// 1. 動態分配int的空間   然後賦值
    int *p = malloc(sizeof(int));
    *p = 89;

// 2. 在堆中存儲4個整型數
    int *p = malloc(sizeof(int) * 4);
    for (int i = 0; i < 4; i++) {
        *(p+i) = i;
    }
    for (int i = 0; i < 4; i++) {
        printf("%d   ",*(p+i));
    }

//3. 在堆中存儲一個人名
    char *p = malloc(sizeof(char) * 20);
    strcpy(p, "zhangsanfeng") ;
    printf("%s  ", p);

//4. 隨機產生10個30--45之間的隨機數,存儲在堆內存中
    int *p = malloc(sizeof(int) * 10);
    for (int i = 0; i < 10; i++) {
        *(p+i) = arc4random() % 16 + 30;
    }
    for (int i = 0; i < 10; i++) {
        printf("%d   ",*(p+i));
    }

例1:
有一個字符串,裏面包含數字,提取出裏面的數字,然後動態分配內存存儲

    char p[] = "BJS150936";
    int len = (int)strlen(p);
    int count = 0;
    for (int i = 0; i < len; i++) {
        if (p[i] >= '0' && p[i] <= '9') {
            count++;
        }
    }
    printf("%d ",count);
    int *pi = malloc(sizeof(int) * count);
    int j = 0;
    for (int i = 0; i < len; i++) {
        if (p[i] >= '0' && p[i] <= '9') {
            pi[j] = p[i] - '0';//將字符轉換爲數字
            j++;
        }
    }
    for (int i = 0; i < count; i++) {
        printf("%d   ", pi[i]);
    }

5.4. free() 函數:內存釋放是標記刪除
內存泄露:分配空間之後,沒有回收
野指針:指向了一個已經被回收的內存
malloc函數分配完空間之後,一定要進行釋放,否則產生內存泄露的問題

    int *p = malloc(sizeof(int));
    *p = 20;
    free(p);
    printf("%d", *p); //  <---野指針:指向了一個被回收的內存
    // 剛釋放的內存沒有被使用,所以暫時沒有報錯  
    // 打印結果是:20

5.5 其他的內存分配函數:

// 1. void  *calloc(size_t, size_t);  第一個是申請幾個   第二個是數據類型的字節
/*
calloc = clear allocation
 1. 在堆內存分配n個size字節的空間,並返回地址
 2. 會將分配的存儲空間中原有的數據清空
*/

//1.1 在堆中存儲5個整型數,範圍是15--35之間的隨機數
    int *p = calloc(5, sizeof(int));
    for (int i = 0; i < 5; i++) {
        p[i] = arc4random() % 21 + 15;
    }
    for (int i = 0; i < 5; i++) {
        printf("%d  ", p[i]);
    }
    free(p);  //  死也不能忘記釋放內存呀!!!!!!  malloc  calloc都需要程序員釋放的呀


// 2. void  *realloc(void *, size_t);   按給定的地址及給定的大小重新分配  釋放新的內存, 舊的不用
    int *p = malloc(sizeof(10));
    int *ps = realloc(p, 20);
    printf("p = %p,  ps = %p\n", p, ps);

    /* 結果:p = 0x10020dd40,  ps = 0x10020ae70 給p重新分配20個字節,地址0x10020dd40不夠20個,
    所以重新開闢了一塊空間,分配20個給p。
    不用釋放p,需要釋放後來分配的空間---ps ~~~~~~~~~~
    */

5.6. 內存操作函數:


**初始化內存**

// 1.void *memset(void *s, int, c size_t n);  從s指向的地址開始,將n個字節初始化爲int c
   int *p = malloc(sizeof(int));
   memset(p, 0, sizeof(int));

 ** 內存拷貝 **  
// 2.void   *memcpy(void *dest, const void *source, size_t n);從source開始,拷貝n個字節到dest
   char str1[] = "bjS140936";
   char str2[] = "15";
   memcpy(str1, "BJ", 2);
   memcpy(str1+3, str2, 2);
   printf("%s  ", str1);
   // 結果:BJS150936 

 ** 內存比較 **  
/* 3. int memcmp(const void *buf1, const void *buf2, size_t count);比較 buf1和buf2指向的內存是否相同,比較count個字節
*/

// 例3.1 定義兩個整型指針,分別⽤malloc、calloc對其分配空間保存3個元素,malloc分配的空間⽤用memset清零,隨機對數組進⾏行賦值隨機範圍1-3,賦值後⽤用memcmp⽐比較兩個數組。如果相同打印Good!否則打印Failed...
    int *p1= malloc(sizeof(int) * 3);
    memset(p1, 0, sizeof(int) * 3);
    int *p2 = calloc(3, sizeof(int));
    for (int i = 0; i < 3; i++) {
        *(p1 + i) = arc4random() % 3 + 1;
        *(p2 + i) = arc4random() % 3 + 1;
     }
     int a = memcmp(p1, p2, sizeof(int) * 3);
     printf("%d  ",a); //  a<0  也就是Failed
發佈了44 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章