C++ Phân bổ động của mảng với ví dụ

Mảng động là gì?

Mảng động khá giống với mảng thông thường nhưng kích thước của nó có thể thay đổi được trong quá trình chạy chương trình. Các phần tử DynamArray chiếm một khối bộ nhớ liền kề.

Khi một mảng đã được tạo, kích thước của nó không thể thay đổi. Tuy nhiên, mảng động thì khác. Mảng động có thể mở rộng kích thước của nó ngay cả khi nó đã được lấp đầy.

Trong quá trình tạo một mảng, nó được phân bổ một lượng bộ nhớ được xác định trước. Điều này không xảy ra với mảng động vì nó tăng kích thước bộ nhớ theo một hệ số nhất định khi có nhu cầu.

Các yếu tố ảnh hưởng đến hiệu suất của Mảng động

Kích thước ban đầu của mảng và hệ số tăng trưởng của nó quyết định hiệu suất của nó. Lưu ý những điểm sau:

  1. Nếu một mảng có kích thước nhỏ và hệ số tăng trưởng nhỏ, nó sẽ tiếp tục phân bổ lại bộ nhớ thường xuyên hơn. Điều này sẽ làm giảm hiệu suất của mảng.
  2. Nếu một mảng có kích thước lớn và hệ số tăng trưởng lớn, nó sẽ có một lượng lớn bộ nhớ chưa được sử dụng. Do đó, thao tác thay đổi kích thước có thể mất nhiều thời gian hơn. Điều này sẽ làm giảm hiệu suất của mảng.

Từ khóa mới

In C++, chúng ta có thể tạo một mảng động bằng cách sử dụng từ khóa new. Số lượng mục được phân bổ được chỉ định trong một cặp dấu ngoặc vuông. Tên kiểu phải đứng trước tên này. Số lượng mục được yêu cầu sẽ được phân bổ.

cú pháp

Từ khóa mới có cú pháp như sau:

pointer_variable = new data_type;

biến con trỏ là tên của biến con trỏ.

data_type phải hợp lệ C++ loại dữ liệu.

Từ khóa sau đó trả về một con trỏ tới mục đầu tiên. Sau khi tạo mảng động, chúng ta có thể xóa nó bằng từ khóa delete.

Ví dụ 1:

#include<iostream>
using namespace std;
int main() {
	int x, n;
	cout << "Enter the number of items:" << "\n";
	cin >>n;
	int *arr = new int[n];
	cout << "Enter " << n << " items" << endl;
	for (x = 0; x < n; x++) {
		cin >> arr[x];
	}
	cout << "You entered: ";
	for (x = 0; x < n; x++) {
		cout << arr[x] << " ";
	}
	return 0;
}

Đầu ra:

Từ khóa mới

Đây là ảnh chụp màn hình của mã:

Từ khóa mới

Giải thích mã:

  1. Đưa tệp tiêu đề iostream vào chương trình của chúng tôi để sử dụng nó chức năng.
  2. Bao gồm không gian tên std trong chương trình của chúng tôi để sử dụng các lớp của nó mà không cần gọi nó.
  3. Gọi hàm main(). Logic chương trình phải được thêm vào trong phần thân của hàm.
  4. Khai báo hai biến số nguyên x và n.
  5. In một số văn bản trên bảng điều khiển nhắc người dùng nhập giá trị của biến n.
  6. Đọc dữ liệu nhập của người dùng từ bàn phím và gán nó cho biến n.
  7. Khai báo một mảng chứa tổng cộng n số nguyên và gán nó cho biến con trỏ *arr.
  8. In thông báo nhắc người dùng nhập n số mục.
  9. Sử dụng vòng lặp for để tạo biến vòng lặp x để lặp lại các mục được người dùng nhập.
  10. Đọc các phần tử do người dùng nhập vào và lưu trữ chúng trong mảng arr.
  11. Phần cuối của cơ thể vòng lặp for.
  12. In một số văn bản trên bảng điều khiển.
  13. Sử dụng vòng lặp for để tạo biến vòng lặp x để lặp qua các mục của mảng.
  14. In ra các giá trị có trong mảng có tên arr trên bảng điều khiển.
  15. Kết thúc phần thân của vòng lặp for.
  16. Chương trình phải trả về giá trị sau khi hoàn thành thành công.
  17. Phần cuối của hàm main().

LƯU Ý: Trong ví dụ trên, người dùng được phép chỉ định bất kỳ kích thước nào cho mảng trong thời gian chạy. Điều này có nghĩa là kích thước của mảng được xác định trong thời gian chạy.

Đang khởi tạo mảng được phân bổ động

Thật dễ dàng để khởi tạo một mảng động về 0.

Cú pháp:

int *array{ new int[length]{} };

Trong cú pháp trên, độ dài biểu thị số phần tử được thêm vào mảng. Vì chúng ta cần khởi tạo mảng thành 0 nên phần này sẽ để trống.

Chúng ta có thể khởi tạo một mảng động bằng cách sử dụng danh sách khởi tạo. Hãy tạo một ví dụ chứng minh điều này.

Ví dụ 2:

#include <iostream>
using namespace std;

int main(void) {

	int x; 

	int *array{ new int[5]{ 10, 7, 15, 3, 11 } };

	cout << "Array elements: " << endl;

	for (x = 0; x < 5; x++) {

		cout << array[x] << endl;
	}

	return 0;
}

Đầu ra:

Đang khởi tạo mảng được phân bổ động

Đây là ảnh chụp màn hình của mã:

Đang khởi tạo mảng được phân bổ động

Giải thích mã:

  1. Đưa tệp tiêu đề iostream vào chương trình của chúng tôi để sử dụng các chức năng của nó.
  2. Bao gồm không gian tên std trong chương trình của chúng tôi để sử dụng các lớp của nó mà không cần gọi nó.
  3. Gọi hàm main(). Logic chương trình phải được thêm vào trong phần thân của hàm.
  4. Khai báo một biến số nguyên có tên x.
  5. Khai báo một mảng động có tên mảng bằng cách sử dụng danh sách khởi tạo. Mảng sẽ chứa 5 phần tử số nguyên. Lưu ý rằng chúng tôi chưa sử dụng toán tử “=” giữa độ dài mảng và danh sách khởi tạo.
  6. In một số văn bản trên bảng điều khiển. Cuối cùng là một C++ từ khóa có nghĩa là dòng cuối cùng. Nó di chuyển con trỏ đến câu tiếp theo.
  7. Sử dụng vòng lặp for để lặp lại các phần tử của mảng.
  8. In nội dung của mảng có tên mảng trên bàn điều khiển.
  9. Kết thúc phần thân của vòng lặp for.
  10. Chương trình phải trả về giá trị sau khi hoàn thành thành công.
  11. Phần cuối của hàm main().

Thay đổi kích thước mảng

Độ dài của mảng động được đặt trong thời gian phân bổ.

Tuy vậy, C++ không có cơ chế tích hợp sẵn để thay đổi kích thước mảng sau khi nó đã được phân bổ.

Tuy nhiên, bạn có thể vượt qua thách thức này bằng cách phân bổ động một mảng mới, sao chép các phần tử, sau đó xóa mảng cũ.

Lưu ý: kỹ thuật này dễ mắc lỗi, do đó, hãy cố gắng tránh nó.

Tự động xóa mảng

Mảng động sẽ bị xóa khỏi bộ nhớ máy tính sau khi mục đích của nó được hoàn thành. Câu lệnh xóa có thể giúp bạn thực hiện điều này. Dung lượng bộ nhớ được giải phóng sau đó có thể được sử dụng để chứa một bộ dữ liệu khác. Tuy nhiên, ngay cả khi bạn không xóa mảng động khỏi bộ nhớ máy tính, nó sẽ tự động bị xóa sau khi chương trình kết thúc.

Lưu ý:

Để xóa một mảng động khỏi bộ nhớ máy tính, bạn nên sử dụng delete[] thay vì delete. [] hướng dẫn CPU xóa nhiều biến thay vì một biến. Việc sử dụng delete thay vì delete[] khi xử lý mảng động có thể gây ra sự cố. Ví dụ về các vấn đề như vậy bao gồm rò rỉ bộ nhớ, hỏng dữ liệu, treo máy, v.v.

Ví dụ 3:

#include<iostream>
using namespace std;
int main() {
	int x, n;
	cout << "How many numbers will you type?" << "\n";
	cin >>n;
	int *arr = new int[n];
	cout << "Enter " << n << " numbers" << endl;
	for (x = 0; x < n; x++) {
		cin >> arr[x];
	}
	cout << "You typed: ";
	for (x = 0; x < n; x++) {
		cout << arr[x] << " ";
	}
	cout << endl;
	delete [] arr;
	return 0;
}

Đầu ra:

Tự động xóa mảng

Đây là ảnh chụp màn hình của mã:

Tự động xóa mảng

Giải thích mã:

  1. Bao gồm tệp tiêu đề iostream trong chương trình của chúng tôi để sử dụng các chức năng của nó.
  2. Bao gồm không gian tên std trong chương trình của chúng tôi để sử dụng các lớp của nó mà không cần gọi nó.
  3. Gọi hàm main(). Logic chương trình phải được thêm vào trong phần thân của hàm.
  4. Khai báo hai biến x và n kiểu dữ liệu số nguyên.
  5. In một số văn bản trên bảng điều khiển. Văn bản sẽ yêu cầu người dùng cho biết số lượng số họ sẽ nhập.
  6. Đọc đầu vào của người dùng từ bàn phím. Giá trị đầu vào sẽ được gán cho biến n.
  7. Khai báo một biến con trỏ *arr. Mảng arr sẽ dành một phần bộ nhớ để lưu trữ tổng cộng n số nguyên.
  8. In thông báo trên bảng điều khiển nhắc người dùng nhập n số.
  9. Tạo một vòng lặp for và biến vòng lặp x để lặp lại các số được người dùng nhập.
  10. Đọc các số do người dùng nhập vào và lưu vào mảng arr.
  11. Kết thúc phần thân của vòng lặp for.
  12. In một số văn bản trên bảng điều khiển.
  13. Sử dụng vòng lặp for và biến vòng lặp x để lặp lại nội dung của mảng mảng.
  14. In ra các giá trị của mảng arr trên bàn điều khiển.
  15. Kết thúc phần thân của vòng lặp for.
  16. In một dòng trống trên bàn điều khiển.
  17. Giải phóng bộ nhớ của mảng arr.
  18. Chương trình sẽ trả về giá trị khi hoàn thành thành công.
  19. Phần cuối của hàm main().

Tổng kết

  • Mảng thông thường có kích thước cố định. Bạn không thể sửa đổi kích thước của chúng sau khi đã khai báo.
  • Với các loại mảng này, kích thước bộ nhớ được xác định trong thời gian biên dịch.
  • Mảng động thì khác. Kích thước của chúng có thể được thay đổi trong thời gian chạy.
  • Trong mảng động, kích thước được xác định trong thời gian chạy.
  • Mảng động trong C++ được khai báo bằng từ khóa new.
  • Chúng tôi sử dụng dấu ngoặc vuông để chỉ định số lượng mục sẽ được lưu trữ trong mảng động.
  • Sau khi thực hiện xong mảng, chúng ta có thể giải phóng bộ nhớ bằng toán tử xóa.
  • Sử dụng toán tử xóa với [] để giải phóng bộ nhớ của tất cả các phần tử mảng.
  • Việc xóa mà không có [] sẽ chỉ giải phóng bộ nhớ của một phần tử duy nhất.
  • Không có cơ chế tích hợp để thay đổi kích thước C++ mảng.
  • Để khởi tạo một mảng bằng trình khởi tạo danh sách, chúng ta không sử dụng toán tử “=”.

Tìm hiểu thêm về PNV Xem tiếp