【C 語言入門】186.重新配置記憶體

在上一篇文章我們有提過,如果要讓使用者可以輸入任意個整數後,將所有輸入的整數一起印出(輸入 0 表示結束)。

我們也驗證了用以下的程式是 ok 的。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *numbers = 0;            //0 表示空指標 (NULL)
    int length = 0;              //目前已經輸入的數字個數
    while(1){
        int input;
        scanf("%d", &input);     //從鍵盤輸入數字
        if(input == 0) break;    //如果輸入的數字為0則結束
        int* larger = malloc(sizeof(int) * (length+1));   //產生一個大一格的新陣列
        for(int i =0; i < length ;i++) larger[i] = numbers[i];//複製舊陣列到新陣列
        free(numbers);
        numbers = larger;        //將 numbers 設為剛產生的新陣列
        numbers[length] = input; //將輸入數字放在最後面
        length++;                //將已輸入的數字個數加1
    }
    printf("Numbers: ");
    for(int i = 0; i < length; i++){ //數每個輸入的數字
        printf("%d", numbers[i]);
    }
    printf("\n");
    return 0;
}

程式中加粗的地方其實就是重新配置記憶體空間的概念,也就是把一個比較小的記憶體空間,變成一個比較大的記憶體空間的過程。

C 語言在標準函式庫提供了一個函式,叫做 reallocation。

我們可以使用 reallocation 函式重新配置記憶體的大小。

<stdlib.h> 提供 realloc 函式複製記憶體的內容。

void* realloc(void* ptr, size_t size);

第一個參數 ptr,就是原本我們資料所存放的位置,由 malloc 或其他動態記憶體配置和數所配置。

第二個參數是 size,是重新配置後的記憶體空間大小(單位為位元組)。

也就是我們預期新的空間有多大,我們會跟 size 講原本的資料在哪,然後新的藥有多大之後,size 就會去配置一個新的記憶體空間,然後回傳給我們。

上述四行加粗的程式碼,就可以簡化為一行。

numbers = realloc(numbers,sizeof(int) * (length + 1)); //重新配置新陣列

重新配置之後,再把記憶體空間的位置存放在 numbers 裡面。

除了簡化函式之外,這個函式還有一個重要的用途。

假設我們原先配置了 3 個空間的陣列。如果 realloc 知道後面的格子沒有人使用的話,就可以直接把3 的空間的陣列長大成 4 格。

換句話說,這個函式所回傳的記憶體位址,有可能跟原本我傳進去記憶體位址的是同一個,因為他可能不需要搬家,這樣會更有效率。

今天如果我們要考慮重新分配記憶體空間大小的時候,可以先使用 realloc 來做。

使用 realloc 的程式

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *numbers = 0;            //0 表示空指標 (NULL)
    int length = 0;              //目前已經輸入的數字個數
    while(1){
        int input;
        scanf("%d", &input);     //從鍵盤輸入數字
        if(input == 0) break;    //如果輸入的數字為0則結束
        numbers = realloc(numbers,sizeof(int) * (length + 1)); //重新配置新陣列
        numbers[length] = input; //將輸入數字放在最後面
        length++;                //將已輸入的數字個數加1
    }
    printf("Numbers: ");
    for(int i = 0; i < length; i++){ //數每個輸入的數字
        printf("%d", numbers[i]);
    }
    printf("\n");
    return 0;
}

Leave a Comment

Your email address will not be published. Required fields are marked *