Dalam C, pengurusan memori dinamik merupakan aspek penting untuk membangunkan perisian yang cekap, terutamanya dalam aplikasi kritikal prestasi. Walaupun fungsi seperti malloc() dan free() dalam perpustakaan standard biasa digunakan, ia datang dengan overhed dan pengehadan, seperti pemecahan dan masa peruntukan yang lebih perlahan apabila dipanggil dengan kerap. Satu penyelesaian kepada isu ini ialah mencipta pembahagian kolam memori.
Dalam blog ini, kami akan menerangkan cara menulis pengalokasi kumpulan memori ringkas dari awal dalam C. Dengan menggunakan kumpulan memori, kami boleh pra-peruntukkan blok memori yang besar dan mengurusnya secara manual, mengurangkan pemecahan dan meningkatkan memori prestasi peruntukan.
Pengumpuk memori ialah strategi pengurusan memori tersuai di mana blok memori yang besar telah diperuntukkan terlebih dahulu dan sebahagian kecil daripadanya diserahkan kepada program mengikut keperluan. Apabila memori tidak lagi diperlukan, ia dikembalikan ke kolam untuk digunakan semula. Pendekatan ini membolehkan peruntukan dan deallocation yang lebih pantas daripada menggunakan malloc() dan free() secara langsung, serta penggunaan memori yang lebih baik.
Begini cara kumpulan memori asas berfungsi:
Kami akan bermula dengan mentakrifkan struktur ringkas untuk kumpulan memori dan blok di dalamnya. Setiap blok akan mempunyai penunjuk ke blok seterusnya dalam senarai percuma, yang membolehkan kami memperuntukkan dan membebaskan memori dengan cepat.
#include <stdio.h> #include <stdlib.h> #include <stddef.h> #define POOL_SIZE 1024 // Total memory pool size // Define a block structure with a pointer to the next free block typedef struct Block { struct Block *next; } Block; // Define the MemoryPool structure typedef struct { Block *freeList; unsigned char pool[POOL_SIZE]; // Pre-allocated pool } MemoryPool;
Dalam kod ini:
Untuk memulakan kumpulan memori, kita perlu membahagikan kumpulan itu kepada blok dan menyediakan senarai percuma. Setiap blok harus menghala ke blok percuma seterusnya.
void initMemoryPool(MemoryPool *pool) { pool->freeList = (Block *)pool->pool; Block *current = pool->freeList; // Create a free list of blocks for (int i = 0; i < (POOL_SIZE / sizeof(Block)) - 1; i++) { current->next = (Block *)((unsigned char *)current + sizeof(Block)); current = current->next; } current->next = NULL; // Last block points to NULL }
Dalam fungsi ini:
Untuk memperuntukkan memori, kita perlu mendapatkan blok pertama yang tersedia daripada senarai percuma. Sebaik sahaja kami memperuntukkan blok, kami mengalih keluarnya daripada senarai percuma.
#include <stdio.h> #include <stdlib.h> #include <stddef.h> #define POOL_SIZE 1024 // Total memory pool size // Define a block structure with a pointer to the next free block typedef struct Block { struct Block *next; } Block; // Define the MemoryPool structure typedef struct { Block *freeList; unsigned char pool[POOL_SIZE]; // Pre-allocated pool } MemoryPool;
Fungsi ini menyemak sama ada senarai percuma kosong. Jika tidak, ia mengambil blok percuma pertama, mengalih keluarnya daripada senarai percuma dan mengembalikannya kepada pemanggil.
Apabila memori dibebaskan, kami mengembalikan blok itu ke senarai percuma. Ini membolehkan ia digunakan semula untuk peruntukan masa hadapan.
void initMemoryPool(MemoryPool *pool) { pool->freeList = (Block *)pool->pool; Block *current = pool->freeList; // Create a free list of blocks for (int i = 0; i < (POOL_SIZE / sizeof(Block)) - 1; i++) { current->next = (Block *)((unsigned char *)current + sizeof(Block)); current = current->next; } current->next = NULL; // Last block points to NULL }
Di sini, kami menambah blok yang dibebaskan ke hadapan senarai percuma dengan menetapkan penuding seterusnya kepada blok pertama semasa dalam senarai percuma. Ini membolehkan blok itu digunakan semula pada masa hadapan.
Sekarang kita mempunyai semua fungsi yang diperlukan, mari kita susun semuanya dan uji pengalokasi kolam memori kita.
void *allocateMemory(MemoryPool *pool) { if (pool->freeList == NULL) { printf("Memory pool exhausted!\n"); return NULL; } // Get the first free block Block *block = pool->freeList; pool->freeList = block->next; // Move the free list pointer return (void *)block; }
Dalam contoh ini:
Apabila anda menjalankan program ini, anda akan melihat output yang serupa dengan ini:
void freeMemory(MemoryPool *pool, void *ptr) { Block *block = (Block *)ptr; block->next = pool->freeList; // Add the block to the free list pool->freeList = block; }
Kolam memori amat berguna dalam sistem masa nyata, sistem terbenam dan permainan, di mana kependaman rendah dan kecekapan memori adalah kritikal.
Menulis pengalokasi kumpulan memori anda sendiri boleh mengoptimumkan pengurusan memori dengan ketara untuk aplikasi kritikal prestasi. Dengan menguruskan memori secara langsung, anda boleh meningkatkan kelajuan peruntukan, mengurangkan pemecahan dan mendapatkan lebih kawalan ke atas cara memori digunakan dalam program anda. Walaupun contoh ini adalah asas, anda boleh melanjutkannya dengan ciri tambahan seperti saiz blok yang berbeza atau peruntukan memori selamat benang.
Jika anda sedang mengusahakan projek yang memerlukan pengurusan memori yang cekap, pertimbangkan untuk melaksanakan kumpulan memori anda sendiri. Ini adalah cara yang bagus untuk menyelami lebih mendalam ke dalam pengurusan memori dan meningkatkan prestasi aplikasi anda.
Sila hubungi jika anda mempunyai sebarang pertanyaan atau memerlukan penjelasan lanjut. Selamat mengekod! ?
Atas ialah kandungan terperinci Menulis Peruntukan Kolam Memori Anda Sendiri dalam C. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!