Mình nhớ mình có gặp và có trả lời về vấn đề tương tự trên daynhauhoc rồi, nhưng không nhớ chỗ nào để tìm lại cho bạn. Trước đây mình cũng từng bị lỗi này vì không hiểu rõ cách C gọi hàm và con trỏ.
Bạn có thể hiểu đơn giản là truyền con trỏ vào hàm chỉ là truyền địa chỉ vùng nhớ (chỉ là 1 con số 4 bytes với 32bit và 8 bytes với 64bit). Và khi bạn dùng new
hay malloc
, nó sẽ yêu cầu hệ điều hành cấp phát một vùng nhớ tương ứng, và vùng nhớ này sẽ có địa chỉ khác với địa chỉ vùng nhớ ban đầu của nó.
Khi khai báo con trỏ *a
, nó nhất định sẽ trỏ tới đâu đó có địa chỉ tạm gọi là 0xA
, khi truyền vào hàm (như ví dụ của bạn) thì giá trị truyền vào là 0xA
, biến nội bộ tên là c
sẽ giữ giá trị này, rồi bạn xin thêm vùng nhớ qua new
, HĐH trả về vùng nhớ 0xC
và biến c
giữ giá trị này, giờ thì nó đã ghi đè vào biến c
, biến c
không còn biết tới vùng nhớ có địa chỉ 0xA
nữa. Mọi thao tác bây giờ xung quanh đến vùng nhớ 0xC
và vùng nhớ ban đầu 0xA
của biến a
không bị tác động đến. Nên biến a
bình tĩnh sống, hàm đó không ảnh hưởng gì đến nó cả.
Giống như thế này:
void useless_fn(int num1, int num2) {
num1 = 399;
num2 = 0;
}
int main() {
int a=1, b=2;
useless_fn(a, b);
}
Vậy, nó khá là vô nghĩa. Giá trị truyền vào không được sử dụng.
Giải quyết:
- Đã khai báo a, b là biến toàn cục, bạn có thể gọi thẳng a, b trong hàm
enter
nhưng điều này là xấu và mình không khuyến khích.
- Cấp phát trước khi gọi hàm và không cấp phát lại trong hàm.
- Sử dụng con trỏ cấp 2, bạn có thể đọc bài về con trỏ trỏ đến con trỏ để biết cách sử dụng. Cách này có vể hợp hơn nhưng sẽ phức tạp hơn.
- Riêng C++ còn có “references”, nhưng mình không rành để giải thích cho bạn. Bạn tự tìm hiểu. Trên daynhauhoc chắc sẽ có.