Trước khi bạn học C Phân bổ bộ nhớ động, hãy hiểu:
Quản lý bộ nhớ trong C hoạt động như thế nào?
Khi bạn khai báo một biến bằng kiểu dữ liệu cơ bản, trình biên dịch C sẽ tự động phân bổ không gian bộ nhớ cho biến trong một nhóm bộ nhớ được gọi là ngăn xếp .
Ví dụ, một biến float thường mất 4 byte (theo nền tảng) khi nó được khai báo. Chúng tôi có thể xác minh thông tin này bằng cách sử dụng toán tử sizeof như được hiển thị trong ví dụ dưới đây
#includeint main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
Đầu ra sẽ là:
The size of float is 4 bytes
Ngoài ra, một mảng có kích thước xác định được cấp phát trong các khối bộ nhớ liền kề, mỗi khối có kích thước cho một phần tử:
#includeint main() { float arr[10];printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
Kết quả là:
The size of the float array with 10 element is 40
Như đã học cho đến nay, khi khai báo một kiểu dữ liệu cơ bản hoặc một mảng, bộ nhớ sẽ tự động được quản lý. Tuy nhiên, có một quy trình cấp phát bộ nhớ trong C sẽ cho phép bạn triển khai một chương trình trong đó kích thước mảng không được quyết định cho đến khi bạn chạy chương trình của mình (thời gian chạy). Quá trình này được gọi là "Cấp phát bộ nhớ động ".
Trong hướng dẫn này, bạn sẽ học-
- Quản lý bộ nhớ trong C hoạt động như thế nào?
- Phân bổ bộ nhớ động trong C
- C malloc () Hàm
- Hàm miễn phí ()
- C calloc () Hàm
- calloc () so với malloc (): Sự khác biệt chính
- C realloc () Hàm
- Mảng động
Phân bổ bộ nhớ động trong C
Phân bổ bộ nhớ động là phân bổ thủ công và giải phóng bộ nhớ theo nhu cầu lập trình của bạn. Bộ nhớ động được quản lý và phục vụ với các con trỏ trỏ đến không gian bộ nhớ mới được cấp phát trong một khu vực mà chúng ta gọi là heap.
Giờ đây, bạn có thể tạo và hủy động một mảng các phần tử trong thời gian chạy mà không gặp bất kỳ sự cố nào. Tóm lại, quản lý bộ nhớ tự động sử dụng ngăn xếp và Phân bổ bộ nhớ động C sử dụng đống.
Thư viện
Chức năng | Mục đích |
malloc () | Phân bổ bộ nhớ có kích thước được yêu cầu và trả về con trỏ đến byte đầu tiên của không gian được cấp phát. |
calloc () | Phân bổ không gian cho các phần tử của một mảng. Khởi tạo các phần tử bằng 0 và trả về một con trỏ vào bộ nhớ. |
realloc () | Nó được sử dụng để sửa đổi kích thước của không gian bộ nhớ được cấp phát trước đó. |
Miễn phí() | Giải phóng hoặc làm trống không gian bộ nhớ được cấp phát trước đó. |
Hãy thảo luận về các chức năng trên với ứng dụng của chúng
C malloc () Hàm
Hàm C malloc () là viết tắt của cấp phát bộ nhớ. Nó là một hàm được sử dụng để cấp phát động một khối bộ nhớ. Nó dự trữ không gian bộ nhớ có kích thước được chỉ định và trả về con trỏ null trỏ đến vị trí bộ nhớ. Con trỏ trả về thường có kiểu void. Nó có nghĩa là chúng ta có thể gán hàm C malloc () cho bất kỳ con trỏ nào.
Cú pháp của hàm malloc ():
ptr = (cast_type *) malloc (byte_size);
Đây,
- ptr là một con trỏ của cast_type.
- Hàm C malloc () trả về một con trỏ đến vùng nhớ được cấp phát byte_size.
Ví dụ về malloc ():
Example: ptr = (int *) malloc (50)
Khi câu lệnh này được thực thi thành công, một không gian bộ nhớ 50 byte sẽ được bảo lưu. Địa chỉ của byte đầu tiên của không gian dành riêng được gán cho con trỏ ptr kiểu int.
Hãy xem xét một ví dụ khác:
#includeint main(){int *ptr;ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */if (ptr != NULL) {*(ptr + 5) = 480; /* assign 480 to sixth integer */printf("Value of the 6th integer is %d",*(ptr + 5));}}
Đầu ra:
Value of the 6th integer is 480
- Lưu ý rằng sizeof (* ptr) đã được sử dụng thay vì sizeof (int) để làm cho mã mạnh hơn khi khai báo * ptr được đánh máy thành một kiểu dữ liệu khác sau này.
- Việc cấp phát có thể không thành công nếu bộ nhớ không đủ. Trong trường hợp này, nó trả về một con trỏ NULL. Vì vậy, bạn nên bao gồm mã để kiểm tra một con trỏ NULL.
- Hãy nhớ rằng bộ nhớ được cấp phát là liền kề và nó có thể được coi là một mảng. Chúng ta có thể sử dụng số học con trỏ để truy cập các phần tử của mảng hơn là sử dụng dấu ngoặc []. Chúng tôi khuyên bạn nên sử dụng + để tham chiếu đến các phần tử mảng vì việc sử dụng tăng ++ hoặc + = sẽ thay đổi địa chỉ được lưu trữ bởi con trỏ.
Hàm Malloc () cũng có thể được sử dụng với kiểu dữ liệu ký tự cũng như các kiểu dữ liệu phức tạp như cấu trúc.
Hàm miễn phí ()
Bộ nhớ cho các biến được tự động phân bổ tại thời điểm biên dịch. Trong cấp phát bộ nhớ động, bạn phải phân bổ bộ nhớ một cách rõ ràng. Nếu không thực hiện, bạn có thể gặp phải lỗi hết bộ nhớ.
Hàm free () được gọi để giải phóng / phân bổ bộ nhớ trong C. Bằng cách giải phóng bộ nhớ trong chương trình của bạn, bạn sẽ có nhiều bộ nhớ hơn để sử dụng sau này.
Ví dụ:
#includeint main() {int* ptr = malloc(10 * sizeof(*ptr));if (ptr != NULL){*(ptr + 2) = 50;printf("Value of the 2nd integer is %d",*(ptr + 2));}free(ptr);}
Đầu ra
Value of the 2nd integer is 50
C calloc () Hàm
Hàm C calloc () là viết tắt của phân bổ liền kề. Hàm này được sử dụng để cấp phát nhiều khối bộ nhớ. Nó là một chức năng cấp phát bộ nhớ động được sử dụng để cấp phát bộ nhớ cho các cấu trúc dữ liệu phức tạp như mảng và cấu trúc.
Hàm malloc () được sử dụng để cấp phát một khối không gian bộ nhớ trong khi hàm calloc () trong C được sử dụng để cấp phát nhiều khối không gian bộ nhớ. Mỗi khối được cấp phát bởi hàm calloc () có cùng kích thước.
Cú pháp của hàm calloc ():
ptr = (cast_type *) calloc (n, size);
- Câu lệnh trên dùng để cấp phát n khối nhớ có cùng kích thước.
- Sau khi không gian bộ nhớ được cấp phát, thì tất cả các byte được khởi tạo bằng 0.
- Con trỏ hiện đang ở byte đầu tiên của không gian bộ nhớ được cấp phát được trả về.
Bất cứ khi nào có lỗi phân bổ không gian bộ nhớ chẳng hạn như thiếu bộ nhớ, thì con trỏ null sẽ được trả về.
Ví dụ về calloc ():
Chương trình dưới đây tính tổng của một dãy số học.
#includeint main() {int i, * ptr, sum = 0;ptr = calloc(10, sizeof(int));if (ptr == NULL) {printf("Error! memory not allocated.");exit(0);}printf("Building and calculating the sequence sum of the first 10 terms \ n ");for (i = 0; i < 10; ++i) { * (ptr + i) = i;sum += * (ptr + i);}printf("Sum = %d", sum);free(ptr);return 0;}
Kết quả:
Building and calculating the sequence sum of the first 10 termsSum = 45
calloc () so với malloc (): Sự khác biệt chính
Sau đây là sự khác biệt chính giữa malloc () Vs calloc () trong C:
Hàm calloc () thường phù hợp và hiệu quả hơn hàm malloc (). Trong khi cả hai hàm đều được sử dụng để cấp phát không gian bộ nhớ, hàm calloc () có thể cấp phát nhiều khối cùng một lúc. Bạn không phải yêu cầu khối bộ nhớ mỗi lần. Hàm calloc () được sử dụng trong các cấu trúc dữ liệu phức tạp đòi hỏi không gian bộ nhớ lớn hơn.
Khối bộ nhớ được cấp phát bởi một calloc () trong C luôn được khởi tạo bằng 0 trong khi trong hàm malloc () trong C, nó luôn chứa một giá trị rác.
C realloc () Hàm
Sử dụng hàm C realloc () , bạn có thể thêm nhiều dung lượng bộ nhớ hơn vào bộ nhớ đã được cấp phát. Nó mở rộng khối hiện tại trong khi vẫn giữ nguyên nội dung ban đầu. realloc () trong C là viết tắt của phân bổ lại bộ nhớ.
realloc () cũng có thể được sử dụng để giảm kích thước của bộ nhớ đã được cấp phát trước đó.
Cú pháp của hàm realloc ():
ptr = realloc (ptr,newsize);
Câu lệnh trên cấp phát một không gian bộ nhớ mới với kích thước được chỉ định trong biến newsize. Sau khi thực hiện hàm, con trỏ sẽ được trả về byte đầu tiên của khối bộ nhớ. Kích thước mới có thể lớn hơn hoặc nhỏ hơn bộ nhớ trước đó. Chúng tôi không thể chắc chắn rằng nếu khối mới được cấp phát sẽ trỏ đến cùng một vị trí với vị trí của khối bộ nhớ trước đó. Chức năng này sẽ sao chép tất cả dữ liệu trước đó trong vùng mới. Nó đảm bảo rằng dữ liệu sẽ vẫn an toàn.
Ví dụ về realloc ():
#includeint main () {char *ptr;ptr = (char *) malloc(10);strcpy(ptr, "Programming");printf(" %s, Address = %u\n", ptr, ptr);ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new sizestrcat(ptr, " In 'C'");printf(" %s, Address = %u\n", ptr, ptr);free(ptr);return 0;}
Bất cứ khi nào hàm realloc () trong C dẫn đến một hoạt động không thành công, nó sẽ trả về một con trỏ null và dữ liệu trước đó cũng được giải phóng.
Mảng động trong C
Mảng Động trong C cho phép số lượng phần tử tăng lên khi cần thiết. C Mảng động được sử dụng rộng rãi trong các thuật toán Khoa học máy tính.
Trong chương trình sau, chúng tôi đã tạo và thay đổi kích thước một mảng Động trong C
#includeint main() {int * arr_dynamic = NULL;int elements = 2, i;arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocksfor (i = 0; i < elements; i++) arr_dynamic[i] = i;for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);elements = 4;arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elementsprintf("After realloc\n");for (i = 2; i < elements; i++) arr_dynamic[i] = i;for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);free(arr_dynamic);}
Kết quả chương trình mảng C động tại màn hình:
arr_dynamic[0]=0arr_dynamic[1]=1After reallocarr_dynamic[0]=0arr_dynamic[1]=1arr_dynamic[2]=2arr_dynamic[3]=3
Tóm lược
- Chúng tôi có thể quản lý động bộ nhớ bằng cách tạo các khối bộ nhớ khi cần thiết trong heap
- Trong Phân bổ bộ nhớ động C, bộ nhớ được cấp phát tại một thời điểm chạy.
- Cấp phát bộ nhớ động cho phép thao tác với các chuỗi và mảng có kích thước linh hoạt và có thể thay đổi bất cứ lúc nào trong chương trình của bạn.
- Nó được yêu cầu khi bạn không biết một cấu trúc cụ thể sẽ chiếm bao nhiêu bộ nhớ.
- Malloc () trong C là một hàm cấp phát bộ nhớ động, viết tắt của cấp phát bộ nhớ khối bộ nhớ có kích thước cụ thể được khởi tạo thành giá trị rác
- Calloc () trong C là một hàm cấp phát bộ nhớ liền kề cấp phát nhiều khối bộ nhớ tại một thời điểm được khởi tạo bằng 0
- Realloc () trong C được sử dụng để phân bổ lại bộ nhớ theo kích thước được chỉ định.
- Hàm Free () được sử dụng để xóa bộ nhớ được cấp phát động.