Trang chủ » Bài 14 – Cấp phát động
Lập trình C/C++

Bài 14 – Cấp phát động

cplusplus

Xin chào mọi người!

Vậy là gần hết hè rồi, buồn thật… Vài tuần nữa là phải bắt đầu năm học mới, thấy mất hết cả sinh lực. Thôi thì vào viết blog để lấy lại sinh khí đã 😀 hehe

Trước giờ mình hay khai báo biến bằng những cách thông thường như int a, double arr[5] đúng không nào? Những cách đó được gọi là cấp phát tĩnh. Và hôm nay mình xin nói sâu hơn về vấn đề cấp phát này!

1. Khái niệm

Cấp phát là thao tác cung cấp vùng nhớ cho biến, mảng, hằng,… Có 2 cách cấp phát là cấp phát tĩnh cấp phát động.

Ví dụ:

// Cấp phát vùng nhớ
double *a = new double; // Cấp phát con trỏ int a
int n = 10;
int *arr = new int[n]; // Cấp phát mảng int arr n phần tử
// Xoá vùng nhớ
delete a; // Xoá biến
delete[] arr; // Xoá mảng

Lưu ý:

  • Ở ví dụ trên, mảng đã có thể cấp phát với số lượng phần tử theo biến. Điều này rất tiện lợi khi ta có thể tính toán chính xác chiều dài của mảng để cấp phát, tránh tình trạng lãng phí bộ nhớ.
  • Những biến cấp phát tĩnh được lưu ở vùng nhớ Stack. Đây là vùng nhớ có kích thước cố định, do vậy có thể thiếu hụt bộ nhớ nếu như cấp phát vùng nhớ lớn. Ngược lại biến cấp phát động lại được lưu ở vùng nhớ Heap/Free Store, đây là vùng nhớ động, có thể mở rộng đến toàn bộ RAM nên sẽ không lo việc thiếu hụt bộ nhớ.
  • Cấp phát động cũng có nhược điểm, đó là cách khai báo phức tạp hơn, ngoài ra bạn phải kiểm soát vùng nhớ mình thật tốt, vì khác như vùng nhớ Stack – nó sẽ tự xoá vùng nhớ khi ra khỏi tầm vực. Nên bạn phải sử dụng 2 cú pháp delete ở trên để tránh tình trạng Memory Leak.

Để hiểu rõ hơn, tưởng tượng nó như sau nhé!

Hồi bé mình rất thích truyện tranh lắm (chả liên quan :v), nên ta cùng giả sử bộ nhớ RAM giống như 1 quầy cho thuê truyện tranh, mà những ô nhớ trong ram chính là những cuốn truyện tranh dễ thương. Quầy thuê truyện tranh được quản lý bởi bà chủ tiệm khó tính (hệ điều hành).

Cùng quay về tuổi thơ qua bài viết này nhé!
Cùng quay về tuổi thơ qua bài viết này nhé!

Ta muốn thuê truyện thì phải đăng kí truyện gì, bao nhiêu quyển với bà chủ tiệm (đâu thể bay vào ôm truyện rồi đi mất được :D). Bà ấy sẽ ghi tên bạn và số lượng truyện mà bạn thuê. Truyện có thể mới (vùng nhớ trống) hoặc cũ do đã có người trước sử dụng mà không bảo quản (vùng nhớ còn giá trị). Nếu có quen biết bà chủ thì bạn có thể thuê được những cuốn truyện hot, mới tinh.

Nói tới đây cái mình muốn đọc truyện tranh quá 😛 thôi tiếp tục vậy…

Khi bạn đọc xong, bạn phải trả lại cho bà chủ tiệm (delete). Bạn có làm rách, bẩn cũ xì cuốn truyện thì bà chủ tiệm cũng không quan tâm, chỉ quan tâm số lượng truyện bạn trả có đủ với sổ ghi không. Và cứ thế nếu người ta có thuê lại cuốn truyện cũ mà bạn vừa làm đổ chè, kem, các thứ linh tinh lên đấy, thì xui cho họ phải chịu nhịn mà đọc (bây giờ xịn hơn rồi, người ta kiểm tra truyện có bị gì thì đền :P)

Cấp phát động cũng tương tự, khi bạn cấp phát động thì bạn phải đăng kí với hệ điều hành là mình xin bao nhiêu vùng nhớ. Vùng nhớ đó chứa những giá trị ngẫu nhiên, có thể null, cũng có thể có giá trị cũ. Ta có thể ép nó để có vùng nhớ có giá trị như ta mong muốn (quen biết bà chủ quán).

Khi ta xài xong, ta phải khai báo delete/delete[] để giải phóng vùng nhớ. Con trỏ khi delete không thay đổi địa chỉ (sách cũ dính chè, kem,…), bạn cần phải phân biệt được địa chỉ con trỏ và giá trị nó trỏ đến (có thể học lại 2 phần bài 9 và 10 về con trỏ). Nhưng nếu bạn cấp phát mà không giải phóng vùng nhớ thì sẽ xảy ra tình trạng Memory Leak, nó sẽ làm cho bộ nhớ càng ít (giống như thuê truyện xong ăn quỵt không trả cho người ta ấy).

2. Vùng nhớ trong máy tính

Theo GotW, vùng nhớ máy tính có tất cả 5 loại:

  • Vùng Const Data: vùng này chứa những string literal (giá trị String – mình sẽ giải thích ở mục dưới) và những giá trị khác trong lúc chương trình compile. Vùng này không chứa những dữ liệu kiểu đối tượng (object) trong class. Tất cả những dữ liệu tồn tại trong suốt quá trình chạy chương trình.
  • Vùng Stack: chứa các biến auto (những biến tự nhận kiểu dữ liệu tương ứng với giá trị lúc khởi tạo). Cấp phát trong vùng nhớ này thì nhanh hơn so với cấp phát động (Free Store hay Heap). Những đối tượng được khởi tạo ngay lập tức sau khi bộ nhớ cấp phát, và huỷ ngay khi đối tượng đã ra khỏi tầm vực (scope) của nó. Đây là vùng nhớ cố định.
  • Vùng Free Store: là 1 trong 2 vùng bộ nhớ động, cấp phát bởi new/delete. Vòng đời các đối tượng có thể ngắn hơn so với các đối tượng trong vùng Stack. Vùng nhớ Free Store có thể cấp phát và huỷ rất linh động, an toàn. Trong suốt quá trình khi vùng nhớ đó được cấp phát, ta có thể truy cập bằng con trỏ void*.
  • Vùng Heap: là vùng nhớ còn lại trong 2 vùng bộ nhớ động, cấp phát bởi malloc/free. Cần lưu ý rằng trong khi Free Store cấp phát rất linh động và an toàn, Heap lại không được như vậy.
  • Vùng Global/Static: vùng này chứa những biến toàn cục, biến tĩnh,… đươc cấp phát 1 lần ngay khi khởi động chương trình, giữ nguyên suốt cả chương trình, và chỉ bị xoá bỏ khi chương trình kết thúc. Nhược điểm là nếu vùng nhớ có kích thước quá lớn sẽ chiếm dụng nhiều bộ nhớ hệ thống, vì vậy không khuyến khích khai báo quá nhiều trong vùng này, chỉ khai báo khi cần thiết (theo diễn đàn cộng đồng C việt)

String literal (hay còn gọi là Giá trị string) là đoạn text nằm giữa 2 dấu nháy kép . String literal là hằng, nó có kiểu const char*.

Cùng xét ví dụ sau để hiểu rõ về string literal nhé (mình xin dùng C để giải thích rõ hơn):

char buffer[] = "Hello world";
char * const p1 = buffer; // Hằng con trỏ
char const * p2 = buffer; // Con trỏ hằng
p1++; // Báo lỗi
p1[2] = 'i'; // Không vấn đề gì, ta có thể thay đổi các giá trị của chuỗi
p2++; // Không vấn đề
p2[2] = 'i'; // Báo lỗi lúc runtime

Trên đây là bài viết về Cấp phát động trong C++. Cảm ơn các bạn đã chú ý theo dõi! Hẹn gặp lại ở những bài tiếp theo~

Tags

About the author

Võ Hoài Sơn

Tính tình bất định
Chọc vào là bịnh
Rất yêu lập trình
Luôn code hết mình
Mình hiện đang là sinh viên của trường ĐH Khoa học tự nhiên TPHCM. Bản thân rất thích code, kiêm luôn cả mần thơ nên thường hơi hâm hâm dở dở. Ngoài ra chém gió, chém chuối, chém trái cây các kiểu cũng là sở trường của mình. Rất mong được làm quen với các bạn :D

Add Comment