Bộ nhớ động trong C++

Một phần của tài liệu Tài liệu lập trình C++ tiếng Việt (Trang 139)

lập trình viên C++ giỏi. Bộ nhớ trong chương trình C++ của bạn được phân thành hai phần:

Stack: Tất cả biến được khai báo bên trong hàm sẽ nhận bộ nhớ từ stack trong C++.

Heap: Được sử dụng để cấp phát bộ nhớ động khi chương trình chạy.

Nhiều khi, bạn không biết trước bao nhiêu bộ nhớ bạn sẽ cần để lưu thông tin cụ thể trong một biến đã được định nghĩa và kích cỡ bộ nhớ cần thiết có thể được quyết định tại run time.

Bạn có thể cấp phát bộ nhớ tại run time bên trong Heap cho biến đó với một kiểu đã cho bởi sử dụng một toán tử đặc biệt trong C++ mà trả về địa chỉ của không gian đã cấp phát. Toán tử này gọi là toán tử new trong C++.

Nếu bạn không cần thiết bộ nhớ động đã cấp phát nữa, bạn có thể sử dụng toán tử deletetrong C++, sẽ giải phóng bộ nhớ đã được cấp phát trước đó bởi toán tử new.

Toán tử new và delete trong C++

Đây là cú pháp chung để sử dụng toán tử new để cấp phát bộ nhớ động cho bất kỳ kiểu dữ liệu nào trong C++:

new data-type;

Ở đây, data-type có thể là bất kỳ kiểu dữ liệu có sẵn nào ví dụ như mảng hoặc các kiểu dữ liệu tự định nghĩa như lớp hoặc cấu trúc. Đầu tiên, chúng ta xét các kiểu dữ liệu có sẵn. Ví dụ, chúng ta có thể định nghĩa một con trỏ tới kiểu double và sau đó yêu cầu rằng bộ nhớ được cấp phát tại thời gian thực thi. Chúng ta có thể làm điều này bởi sử dụng toán tử newtrong C++ với các lệnh sau:

double* pvalue = NULL; // Pointer initialized with null pvalue = new double; // Request memory for the variable

Bộ nhớ có thể chưa được cấp phát thành công, nếu phần bộ nhớ rỗi (free store) đã được sử dụng. Vì thế, đây là bài thực hành tốt cho bạn khi kiểm tra nếu toán tử new trả về con trỏ NULL và thực hiện hành động thích hợp, như sau:

double* pvalue = NULL; if( !(pvalue = new double ))

http://vietjack.com/ Trang chia sẻ các bài học online miễn phí Trang 140 {

cout << "Error: out of memory." <<endl; exit(1);

}

Hàm malloc() từ C, vẫn tồn tại trong C++, nhưng tôi đề nghị bạn tránh sử dụng hàm malloc() này. Lợi thế lớn nhất của toán tử new so với hàm malloc() là toán tử new không chỉ cấp phát bộ nhớ, nó còn xây dựng đối tượng theo mục đích chính của C++.

Tại bất kỳ thời điểm, khi bạn cảm thấy một biến đã được cấp phát động là không cần thiết nữa, bạn có thể giải phóng bộ nhớ mà nó đã chiếm giữ trong phần bộ nhớ rỗi với toán tửdelete trong C++, như sau:

delete pvalue; // Release memory pointed to by pvalue

Bây giờ, dựa vào các khái niệm trên chúng tôi tạo một ví dụ minh họa cách toán tử new và delete trong C++ làm việc:

#include <iostream> using namespace std;

int main () {

double* pvalue = NULL; // Pointer initialized with null pvalue = new double; // Request memory for the variable

*pvalue = 29494.99; // Store value at allocated address cout << "Value of pvalue : " << *pvalue << endl;

delete pvalue; // free up the memory.

return 0; }

http://vietjack.com/ Trang chia sẻ các bài học online miễn phí Trang 141 Value of pvalue : 29495

Cấp phát bộ nhớ động cho Mảng trong C++

Giả sử bạn muốn cấp phát bộ nhớ cho một mảng ký tự, ví dụ một chuỗi 20 ký tự. Bạn sử dụng cùng cú pháp đã sử dụng ở trên, như sau:

char* pvalue = NULL; // Pointer initialized with null pvalue = new char[20]; // Request memory for the variable

Để xóa mảng mà chúng ta vừa tạo, cú pháp trong C++ là:

delete [] pvalue; // Delete array pointed to by pvalue

Đây là cú pháp chung của toán tử new, bạn có thể sử dụng để cấp phát bộ nhớ cho một mảng đa chiều trong C++:

double** pvalue = NULL; // Pointer initialized with null pvalue = new double [3][4]; // Allocate memory for a 3x4 array

Tuy nhiên, cú pháp để giải phóng bộ nhớ cho mảng đa chiều vẫn giống ở trên:

delete [] pvalue; // Delete array pointed to by pvalue

Cấp phát bộ nhớ động cho Đối tượng trong C++

Đối tượng không khác các kiểu dữ liệu đơn giản. Ví dụ: bạn xem xét code sau, trong đó chúng ta đang sử dụng một mảng đối tượng để làm rõ khái niệm này:

#include <iostream> using namespace std; class Box { public: Box() {

cout << "Constructor called!" <<endl; }

http://vietjack.com/ Trang chia sẻ các bài học online miễn phí Trang 142 cout << "Destructor called!" <<endl;

} };

int main( ) {

Box* myBoxArray = new Box[4];

delete [] myBoxArray; // Delete array

return 0; }

Nếu bạn chuẩn bị cấp phát bộ nhớ cho một mảng 4 đối tượng Box, constructor đơn giản trên sẽ được gọi 4 lần và tương tự trong khi xóa các đối tượng, destructor cũng sẽ được gọi với số lần tương tự.

Biên dịch và thực thi code trên sẽ cho kết quả:

Constructor called! Constructor called! Constructor called! Constructor called! Destructor called! Destructor called! Destructor called! Destructor called! Namespace trong C++

Một phần của tài liệu Tài liệu lập trình C++ tiếng Việt (Trang 139)