Làm sao để truyền giá trị của mảng cấp phát động vào hàm?

Mình thử truyền cấp phát động 2 mảng a, b vào hàm.

#include <iostream>
using namespace std;

int *a;
int *b;

void enter(int *c,int *d)
{
	c=new int[3];
	d=new int[3];
}

int main()
{
	enter(a,b);
}

Nhưng sau khi truyền xong, a, b vẫn giữ nguyên con trỏ null, mình đã mò mấy ngày nhưng chưa biết phải làm sao

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:

  1. Đã 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.
  2. Cấp phát trước khi gọi hàm và không cấp phát lại trong hàm.
  3. 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.
  4. 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ó.
2 Likes

Hi Tran Nhu Thanh.
Cái này liên quan đến tham chiếu tham trị. Với C++ bạn có thể dùng tham chiếu.

3 Likes

Nhưng mình không biết làm sao để tham chiếu con trỏ hết ? :sob:

Thêm & trước tên khi khai báo tham số :smiley:

2 Likes

Mình đã thử trước khi đăng topic này rồi :sob:

#include <iostream>
using namespace std;

int *a;
int *b;

void enter(int **c,int **d)
{
	*c=new int[3];
	*d=new int[3];
}

int main()
{
	enter(&a, &b);
    return 0;
}

bạn dùng pointer to pointer như thế này thử xem sao.

4 Likes

Mình thử được rồi, thanks bạn nhiều

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?