Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Toán tử delete và hàm free() trong C++

Cả delete và free() đều dùng để giải phóng bộ nhớ động, nhưng chúng không thể thay thế lẫn nhau.

Quy tắc vàng

Cấp phát bằngGiải phóng bằng
new / new[]delete / delete[]
malloc() / calloc() / realloc()free()

Sử dụng sai cặp (ví dụ delete cho con trỏ từ malloc) gây hành vi không xác định (undefined behavior).

Ví dụ minh họa đúng/sai

#include <cstdlib> // malloc, free
#include <new>     // bad_alloc

int main() {
    int x = 10;
    int* ptr1 = &x;              // Trỏ đến biến stack
    int* ptr2 = (int*)malloc(sizeof(int)); // Heap qua C
    int* ptr3 = new int;         // Heap qua C++
    int* ptr4 = nullptr;         // Con trỏ null
    
    // --- SAI ---
    delete ptr1; // LỖI NGHIÊM TRỌNG: ptr1 không phải từ new
    delete ptr2; // LỖI: ptr2 từ malloc, phải dùng free()
    
    // --- ĐÚNG ---
    delete ptr3; // OK: ptr3 từ new
    delete ptr4; // OK: delete nullptr an toàn (không làm gì)
    
    // free() cho malloc
    free(ptr2);  // OK
    
    // free(nullptr) cũng an toàn
    free(nullptr);
    
    return 0;
}

Sự khác biệt quan trọng

Đặc điểmdeletefree()
Gọi destructor?CÓ (cho object)KHÔNG
Overload được?CÓ (operator delete)KHÔNG
Xử lý mảng?Cần delete[]Chỉ free() (programmer tự quản lý size)
An toàn với nullptr?CÓCÓ

Lưu ý về delete[]

Luôn dùng delete[] cho mảng được cấp phát bằng new[]. Dùng delete (không có ngoặc vuông) cho mảng sẽ chỉ gọi destructor cho phần tử đầu tiên → rò rỉ bộ nhớ/hủy không hoàn chỉnh.

int* arr = new int[100];
delete[] arr; // ĐÚNG

// Sai:
delete arr;   // Chỉ hủy arr[0], rò rỉ 99 phần tử còn lại

Thực hành hiện đại (Modern C++)

Thay vì quản lý thủ công, hãy dùng smart pointer:

  • std::unique_ptr<T> - sở hữu độc quyền.
  • std::shared_ptr<T> - sở hữu chia sẻ.
  • std::make_unique<T>(), std::make_shared<T>() - an toàn exception.

Với container, dùng std::vector, std::string thay vì mảng động thô.