天天看點

深入學習C語言:C 語言中的記憶體管理機制

作者:嵌入式講堂

嵌入式相關的技術知識

歡迎大家留言讨論,互相交流

關注号主,共同進步

如有錯誤歡迎指正

C語言是一種較為底層的程式設計語言,需要程式員對記憶體管理機制有深入的了解,才能更好地掌控程式的性能和穩定性。本文将詳細介紹C語言中的記憶體管理機制,包括棧與堆、動态記憶體配置設定、常用資料類型的存儲大小和範圍,以及記憶體洩漏等問題。

目錄

  • 棧與堆
  • 動态記憶體配置設定
  • 常用資料類型的存儲大小和範圍
  • 記憶體洩漏問題

棧與堆

在程式執行過程中,需要配置設定記憶體用于存儲各種不同變量,C語言中分為棧和堆兩種存儲方式。棧存儲的變量是局部變量,作用域為函數内部,而堆配置設定的記憶體沒有作用域限制,需要程式員手動釋放。下面分别介紹棧和堆。

棧是一種後進先出(LIFO)的資料結構,在程式運作時,系統自動管理棧及其配置設定的記憶體空間。由于棧是一個區域,需要程式員預測每個變量的記憶體使用情況,如果配置設定了太多記憶體,就會導緻棧溢出(stackoverflow)。

棧主要用于存儲以下類型的變量:

  • 函數的參數
  • 函數中的局部變量
  • 函數調用時的傳回位址

如下面的代碼,函數printInt的三個參數和函數内部的count變量都存儲在棧中:

void printInt(int a, int b, int c) {
    int count = 0;
    printf("%d %d %d %d", a, b, c, count);
}           

堆是一種動态區,程式運作時也需要動态配置設定和釋放空間。堆配置設定的記憶體不會在函數調用結束時自動釋放,需要程式員手動釋放。是以,堆記憶體管理需要謹慎,避免記憶體洩漏或過量配置設定記憶體等問題。

在C語言中,動态記憶體配置設定由以下三個函數完成:

  • void *malloc(size_t size):在堆中配置設定指定大小的連續空間,傳回指向配置設定區域的起始位址。
  • void *calloc(size_t num, size_t size):配置設定num個大小為size的連續空間。并将配置設定的記憶體區域初始化為0。
  • void *realloc(void *ptr, size_t size):重新配置設定空間,擴大或縮小ptr指針所指向的記憶體空間,新的空間大小為size位元組。

下面是使用malloc函數動态配置設定記憶體的例子:

int main () {
    char *str;
    /* 配置設定 25 個位元組的記憶體空間 */
    str = (char *) malloc(25);
    strcpy(str, "C語言中的動态記憶體配置設定");
    printf("字元串是 : %s\n", str);
    /* 釋放剛剛配置設定的記憶體空間 */
    free(str);
    return 0;
}           

在程式中,通過malloc配置設定了25個位元組的記憶體空間,然後通過strcpy函數将字元串指派給配置設定的記憶體位址。最後,釋放已配置設定的記憶體可以使用free函數。

動态記憶體配置設定

動态記憶體配置設定是在程式運作過程中提供新的變量的行為。在使用動态記憶體配置設定時,程式員需要自己負責記憶體的管理。在使用malloc函數時,需要始終記住手動釋放記憶體,避免記憶體洩漏。下面是動态記憶體配置設定的例子:

int main () {
    int i, n;
    int *a;
    printf("請輸入整數的個數:");
    scanf("%d", &n);
    /* 配置設定記憶體空間 */
    a = (int*) malloc (n * sizeof(int));
    printf("請輸入%d個整數:\n", n);
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    printf("輸入的%d個整數是:\n", n);
    for (i = 0; i < n; i++) {
        printf("%d    ", a[i]);
    }
    /* 釋放已配置設定的記憶體 */
    free(a);
    return 0;
}           

在使用malloc配置設定記憶體時,需要指定的是配置設定記憶體的大小,而不是數量。這裡使用n * sizeof(int)計算所需的記憶體大小。在輸入數組a的元素後,程式應通過free函數來釋放已配置設定的記憶體。

常用資料類型的存儲大小和範圍

在 C 語言中,常用的資料類型存儲大小和範圍如下:

資料類型 存儲大小 範圍
char 1 位元組 -128 to 127
short 2 位元組 -32,768 to 32,767
int 4 位元組 -2,147,483,648 to 2,147,483,647
float 4 位元組 約 ±3.4E-38(6 個十進制位)的值範圍
double 8 位元組 約 ±1.7E ±308(15 個十進制位)的值範圍

總結上面的資料類型範圍的規律是:2的n次方

  • char類型是8位二進制數
  • short類型是16位二進制數
  • int 類型是32位二進制數
  • float類型是32位二進制數
  • double類型是64位二進制數

記憶體洩漏問題

在程式運作時,如果配置設定的記憶體沒有釋放,就會出現記憶體洩漏問題,導緻記憶體浪費,進而影響程式的性能和穩定性。在上文中,我們提到了malloc、calloc、realloc和free等函數,這些函數都是用來配置設定和釋放記憶體的。

在使用這些函數時,需要注意以下幾點:

  1. 保證配置設定和釋放記憶體的數量相等。如果程式先配置設定了5個位元組的記憶體,再釋放10個位元組,就會出現野指針等問題。
  2. 确認指針是否已經釋放,避免重複釋放指針。如果多次使用free函數釋放同一個指針,則會出現問題。
  3. 避免将配置設定的指針重新指派,釋放記憶體時使用錯誤的指針是常見的錯誤。

在C語言中,記憶體洩漏是比較常見的問題。程式員需要特别注意記憶體配置設定和釋放的細節,做好記憶體管理工作。

結論

本文主要介紹了C語言中的記憶體管理機制,包括棧與堆、動态記憶體配置設定、常用資料類型的存儲大小和範圍以及記憶體洩漏等問題。C語

歡迎來到【嵌入式講堂】

專注嵌入式技術交流

作業系統,算法,程式設計語言知識分享

歡迎大家一起讨論,讓我們共同進步

繼續閱讀