Các thao tác cơ bản với C++ STL và quản lý bộ nhớ động

Lặp qua các phần tử của một container

Cú pháp vòng lặp dựa trên phạm vi (range-based for loop) cung cấp một cách ngắn gọn để lặp qua tất cả các phần tử trong một container như vector, array, hoặc list.

for (int gia_tri : danh_sach_so) {
    // Xử lý mỗi 'gia_tri' ở đây
}

Vòng lặp này tương đương với việc sử dụng iterator, nhưng cú pháp được đơn giản hóa đáng kể. Dưới đây là một ví dụ sử dụng iterator để kiểm tra sự tồn tại của phần tử trùng lặp trong một vector:

// Giả sử 'danh_sach_so' là một vector<int> và 'tap_hop' là một set<int>
for (vector<int>::iterator it = danh_sach_so.begin(); it != danh_sach_so.end(); ++it) {
    if (tap_hop.find(*it) != tap_hop.end()) {
        cout << "Phần tử trùng lặp đã được tìm thấy!" << endl;
        break;
    }
    tap_hop.insert(*it);
}

Khởi tạo và gán giá trị cho vector

Vector trong C++ có nhiều cách để khởi tạo và gán giá trị.

  • Tạo một vector mới từ vector hiện có: Bạn có thể sao chép toàn bộ nội dung của một vector sang một vector khác.
vector<int> vector_goc = {1, 2, 3, 4};
vector<int> vector_moi(vector_goc); // 'vector_moi' bây giờ chứa {1, 2, 3, 4}
  • Tạo một vector với kích thước đã định trước: Bạn có thể khởi tạo một vector với một kích thước cụ thể, các phần tử sẽ được khởi tạo theo mặc định (0 cho int).
int kich_thuoc = 10;
vector<int> vector_kich_thuoc_dinh_truoc(kich_thuoc); // Vector có 10 phần tử, tất cả đều là 0

Sử dụng new và delete để cấp phát bộ nhớ động

Từ khóa new được sử dụng để cấp phát bộ nhớ trên heap, và delete (hoặc delete[] cho mảng) để giải phóng bộ nhớ đó.

  • Cấp phát một giá trị duy nhất:
int* con_tro_so = new int(42); // Cấp phát một số nguyên có giá trị 42
delete con_tro_so; // Giải phóng bộ nhớ
  • Cấp phát một mảng một chiều:
int* mang_so = new int[50]; // Cấp phát một mảng 50 số nguyên
delete[] mang_so; // Giải phóng bộ nhớ cho mảng
  • Cấp phát mảng hai chiều: Để cấp phát một mảng hai chiều, bạn cần chỉ định số cột. Kết quả trả về là một con trỏ trỏ đến một mảng một chiều.
const int SO_DONG = 3;
const int SO_COT = 4;
int (*con_tro_mang_2d)[SO_COT] = new int[SO_DONG][SO_COT];
// 'con_tro_mang_2d' là một con trỏ trỏ đến một mảng có 4 phần tử kiểu int
delete[] con_tro_mang_2d; // Giải phóng bộ nhớ

Tạo đối tượng bằng new

Có hai cách chính để tạo đối tượng trong C++: trên stack và trên heap (sử dụng new).

  • Tạo đối tượng trên stack: Đối tượng được tạo tự động và hủy tự động khi ra khỏi phạm vi.
LopDoiTuong doi_tuong_stack; // Đối tượng được tạo trên stack
// Không cần gọi delete, hàm hủy sẽ tự động được gọi khi 'doi_tuong_stack' ra khỏi phạm vi
  • Tạo đối tượng trên heap: Đối tượng được tạo bằng new và cần được giải phóng thủ công bằng delete. Con trỏ được sử dụng để truy cập đối tượng.
LopDoiTuong* con_tro_doi_tuong = new LopDoiTuong(); // Tạo đối tượng trên heap
// Sử dụng 'con_tro_doi_tuong' ở nhiều nơi trong chương trình
delete con_tro_doi_tuong; // Bắt buộc phải giải phóng bộ nhớ để tránh rò rỉ bộ nhớ

Ví dụ: Tạo một node cho danh sách liên kết

Dưới đây là một ví dụ về cách sử dụng new để tạo một node mới cho một danh sách liên kết đơn giản.

// Giả sử có một cấu trúc Node như sau:
struct Node {
    int val;
    Node* next;
    Node(int x) : val(x), next(nullptr) {}
};

// Tạo một node giả (dummy) với giá trị 0, trỏ đến node đầu tiên của danh sách
Node* node_gia_tri = new Node(0, node_dau);

Thẻ: C++ STL Vector new delete

Đăng vào ngày 28 tháng 5 lúc 14:29