Bộ nhớ động trong C/C++
Một sự hiểu biết sâu về cách bộ nhớ động thực sự làm việc trong C/C++ là cốt yếu để trở thành một lập trình viên C/C++ giỏi. Bộ nhớ trong chương trình C/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/C++. ...
Một sự hiểu biết sâu về cách bộ nhớ động thực sự làm việc trong C/C++ là cốt yếu để trở thành một lập trình viên C/C++ giỏi. Bộ nhớ trong chương trình C/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/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/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/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ử delete trong C/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/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/C++:
new kieu_du_lieu;
Ở đây, kieu_du_lieu 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ử new trong C/C++ với các lệnh sau:
double* contro = NULL; // con tro duoc khoi tao voi gia tri null contro = new double; // yeu cau bo nho cho bien
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* contro = NULL; if( !(contro = new double )) { cout << "Error: Het bo nho!" <<endl; exit(1); }
Hàm malloc() từ C, vẫn tồn tại trong C/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/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/C++, như sau:
delete contro; // giai phong bo nho duoc tro boi contro
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/C++ làm việc:
#include <iostream> using namespace std; int main () { double* contro = NULL; // con tro duoc khoi tao voi gia tri null contro = new double; // yeu cau bo nho cho bien *contro = 1234.56; // luu giu gia tri tai dia chi da duoc cap phat cout << "Gia tri cua contro la: " << *contro << endl; delete contro; // giai phong bo nho. return 0; }
Biên dịch và chạy chương trình C/C++ trên sẽ cho kết quả sau:
Gia tri cua contro la: 1234.56
Cấp phát bộ nhớ động cho Mảng trong C/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* contro = NULL; // con tro duoc khoi tao voi gia tri null contro = new char[20]; // yeu cau bo nho cho bien
Để xóa mảng mà chúng ta vừa tạo, cú pháp trong C/C++ là:
delete [] contro; // xoa mang da duoc tro boi contro
Đâ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/C++:
double** contro = NULL; // con tro duoc khoi tao voi gia tri null contro = new double [3][4]; // cap phat bo nho cho mang 3x4
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 [] contro; // xoa mang da duoc tro boi contro
Cấp phát bộ nhớ động cho Đối tượng trong C/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 NhanVien { public: NhanVien() { cout << "Constructor duoc goi!" <<endl; } ~NhanVien() { cout << "Destructor duoc goi!" <<endl; } }; int main( ) { NhanVien* mangNhanVien = new NhanVien[5]; delete [] mangNhanVien; // xoa mang return 0; }
Nếu bạn chuẩn bị cấp phát bộ nhớ cho một mảng 5 đối tượng NhanVien, 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à chạy chương trình C/C++ trên sẽ cho kết quả sau:
Mọi người cho thể tham gia khóa học thứ 6 của vietjackteam (đang tuyển sinh) vào đầu tháng 03/2018 do anh Nguyễn Thanh Tuyền, admin vietjack.com trực tiếp giảng dạy tại Hà Nội. Chi tiết nội dung khóa học tham khỏa link : .Các bạn học CNTT, điện tử viễn thông, đa phương tiện, điện-điện tử, toán tin có thể theo học khóa này. Số lượng các công việc Java hoặc .NET luôn gấp ít nhất 3 lần Android hoặc iOS trên thị trường tuyển dụng.
Mọi người có thể xem demo nội dung khóa học tại địa chỉ
Các bạn ở xa học không có điều kiện thời gian có thể tham dự khóa Java online để chủ động cho việc học tập. Trong tháng 4/2018, VietJack khuyến mại giá SỐC chỉ còn 150k cho khóa học, liên hệ facebook admin fb.com/tuyen.vietjack để thanh toán chuyển khoản hoặc thẻ điện thoại, khóa học bằng Tiếng Việt với gần 100 video, các bạn có thể chủ động bất cứ lúc nào, và xem mãi mãi. Thông tin khóa học tại
Loạt bài hướng dẫn học lập trình C++ cơ bản và nâng cao của chúng tôi dựa trên nguồn tài liệu của: Tutorialspoint.com
Follow fanpage của team hoặc facebook cá nhân Nguyễn Thanh Tuyền để tiếp tục theo dõi các loạt bài mới nhất về Java,C,C++,Javascript,HTML,Python,Database,Mobile.... mới nhất của chúng tôi.
Bài học C++ phổ biến khác tại vietjack.com: