首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言動態記憶體管理:realloc 擴展 malloc/calloc 陣列完整範例

     編輯:關於C語言

前言

`realloc` 可調整 `malloc`/`calloc` 分配的記憶體區塊大小,常用於實作動態陣列 (如 C++ `vector` 底層)。本文以學生資料庫為例,示範容量不足時倍增擴容的完整流程。

資料結構設計

typedef struct {
    char name[32];
    int age;
    char gender;
    float score[3];
} Student;

typedef struct {
    Student *pData;  /* 動態陣列基址 */
    int size;        /* 當前容量 (元素數) */
    int count;       /* 實際元素數 */
} Database;

核心函數實作

初始化

int initDatabase(Database *db) {
    db->size = 10;
    db->count = 0;
    db->pData = (Student *)calloc(db->size, sizeof(Student));
    printf("Initial addr: %p\n", db->pData);
    return db->pData ? 0 : -1;
}

銷毀

void destroyDatabase(Database *db) {
    free(db->pData);
    db->pData = NULL;  /* 防止野指標 */
}

插入 (含自動擴容)

int insertData(Database *db, Student stu) {
    if (db->count == db->size) {           /* 容量已滿 */
        db->size *= 2;                     /* 倍增策略 */
        Student *newPtr = (Student *)realloc(db->pData, db->size * sizeof(Student));
        printf("Realloc addr: %p\n", newPtr);
        if (!newPtr) return -1;            /* 擴容失敗 */
        db->pData = newPtr;
    }
    db->pData[db->count++] = stu;          /* 放入新元素 */
    return 0;
}

列印

void printDatabase(Database *db) {
    printf("Size: %d, Count: %d\n", db->size, db->count);
    printf("%-8s %3s %2s %6s %6s %6s\n", "Name", "Age", "G", "Math", "Lang", "Eng");
    for (int i = 0; i < db->count; i++) {
        printf("%-8s %3d %2c %6.2f %6.2f %6.2f\n",
               db->pData[i].name, db->pData[i].age, db->pData[i].gender,
               db->pData[i].score[0], db->pData[i].score[1], db->pData[i].score[2]);
    }
}

主程式測試

int main() {
    srand((unsigned)time(NULL));
    Database db;
    if (initDatabase(&db) != 0) return -1;

    for (int i = 0; i < 20; i++) {
        Student s;
        sprintf(s.name, "name%d", i);
        s.age = rand() % 30;
        s.gender = (rand() % 2) ? 'M' : 'F';
        s.score[0] = rand() % 100;
        s.score[1] = rand() % 100;
        s.score[2] = rand() % 100;
        if (insertData(&db, s) != 0) break;
    }
    printDatabase(&db);
    destroyDatabase(&db);
    return 0;
}

關鍵點總結

  • realloc 行為:嘗試原地擴展;不可則分配新區塊、複製資料、釋放舊區塊。回傳新位址 (可能改變),必須用暫存變數接收,再賦值回結構體,防止失敗導致記憶體洩漏。
  • 倍增策略:均攤時間複雜度 O(1),空間浪費 < 2x。
  • calloc vs malloc:`calloc` 零初始化,適合結構體陣列;`malloc` 未初始化,較快。
  • 錯誤處理:檢查 `realloc` 回傳值,失敗時原指標仍有效,需妥善處理。

總結

掌握 `malloc`/`calloc`/`realloc`/`free` 四大函數與倍增擴容模式,即可實作高效、安全的動態陣列資料結構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved