Con trỏ và địa chỉ trong C, C++
Trong bài học này, bạn sẽ lưu địa chỉ của một biến vào con trỏ, truy cập giá trị qua con trỏ và thay đổi biến gốc.
Giới thiệu
Con trỏ (pointer) là biến lưu địa chỉ bộ nhớ của một biến khác. Toán tử & lấy địa chỉ của một biến, còn toán tử * (gọi là dereference) truy cập giá trị đang nằm tại địa chỉ mà con trỏ trỏ đến. Con trỏ là một trong những khái niệm quan trọng nhất của C và C++.
Những điểm quan trọng
- Con trỏ chỉ được trỏ tới đối tượng còn tồn tại, đúng kiểu dữ liệu, hoặc mang giá trị null.
- Mỗi vùng nhớ được cấp phát chỉ được giải phóng đúng một lần.
- Thể hiện rõ hàm nào sở hữu vùng nhớ (ownership) và dữ liệu nào chỉ được đọc (const).
Code ví dụ bằng C và C++
#include <stdio.h>
int main(void) {
int score = 70;
int *score_ptr = &score;
*score_ptr += 5;
printf("score=%d same-address=%s\n", score,
score_ptr == &score ? "yes" : "no");
return 0;
}
score=75 same-address=yes
#include <iostream>
int main() {
int score = 70;
int* score_ptr = &score;
*score_ptr += 5;
std::cout << "score=" << score << " same-address="
<< std::boolalpha << (score_ptr == &score) << '\n';
}
score=75 same-address=true
So sánh C và C++
Con trỏ score_ptr lưu địa chỉ của score, nên câu lệnh *score_ptr += 5 thực chất cộng thêm 5 vào chính biến score, làm nó tăng từ 70 lên 75. Phép so sánh score_ptr == &score xác nhận hai địa chỉ là một. C++ vẫn dùng con trỏ thô (raw pointer) khi chỉ cần truy cập mà không quản lý vùng nhớ, nhưng thường ưu tiên tham chiếu khi biến không bao giờ được phép rỗng.
Việc sở hữu và giải phóng vùng nhớ hoàn toàn do lập trình viên tự đảm bảo.
Container và RAII tự động giải phóng tài nguyên khi đối tượng hết thời gian tồn tại.
Bài tập mở rộng
Hãy chạy cả hai phiên bản, sau đó thử thay đổi code để quan sát sự khác biệt về mức độ an toàn mà mỗi ngôn ngữ mang lại.
- Thử với con trỏ null và trường hợp cấp phát bộ nhớ thất bại.
- Chạy chương trình với AddressSanitizer và UndefinedBehaviorSanitizer để phát hiện lỗi bộ nhớ.
- Ghi chú rõ con trỏ nào sở hữu vùng nhớ và con trỏ nào chỉ dùng để đọc.
Luyện tập với thử thách
Áp dụng kiến thức của bài học này để giải một bài toán thực tế. Mỗi thử thách chạy ngay trên trình duyệt, có kiểm thử tức thì và AI nhận xét.
Tất cả thử thách