Về biến con trỏ và mảng 1 chiều

mọi người cho em hỏi là em code như thế này thì chương trình không báo lỗi, nhưng chạy chương trình tới lúc nhâp phần tử thứ … thì nó tự động tắt chương trình luôn. Mong mọi người giúp em ạ. Em cảm ơn!

#include<stdio.h>
#include<stdlib.h>
#include<process.h>
#include<conio.h>

void NhapPhanTu(int &n){

	do{
		printf("Nhap vao so  phan tu: ");
		scanf("%d", &n);
		if(n<=0 || n>=100)
			printf("Nhap sai! Nhap lai\n");
	}while(n<=0 || n>=100);
}

void XinCapPhat(int *a, int n){
	a=(int*)malloc(n);
	if(a==NULL){
		printf("Khong du bo nho");
		getch();
		exit(1);
	}
}

void NhapMang(int *a, int n){
	for(int i=0; i<n; i++){
		printf("Phan tu thu %d: ", i);
		scanf("%d", a+i);
	}
}

void XuatMang(int *a, int n){
	for(int i=0; i<n; i++)
		printf("%d\t", *(a+i));
}

int main(){
	
	int n, *a;

	NhapPhanTu(n);
	
	XinCapPhat(a,n);
	
	NhapMang(a, n);
	
	XuatMang(a,n);
	return 0;
}

Đầu tiên là bạn đọc bài viết về cách sử dụng markdown cho cho việc chèn code ở đây.
Sau đó, mình có 1 câu hỏi: tại sao phải phải chia ra thành nhiều hàm khi vấn đề bạn đang giải quyết không có gì lớn? Khi chia ra nhiều hàm, bạn phải cân nhắc và tìm hiểu kỹ về vấn đề truyền con trỏ vào hàm. (Nếu bạn không chia nhiều hàm thì lỗi ít xảy ra!)
Lỗi trong code này xuất phát từ hàm XinCapPhat(), con trỏ a được truyền vào hàm này là địa chỉ con trỏ được khởi tạo ở main(), tại đây bạn lại đi cấp 1 vùng nhớ khác qua malloc(), điều này đồng nghĩa với việc bạn không tác động gì đến vùng nhớ mà con trỏ amain trỏ tới (mình góp ý là đừng bao giờ đặt tên tham số trùng với tên biến, vì khó giải thích cho bạn hiểu). Một lỗi nữa là số bytes mà bạn xin cấp phát, 1 biến int thì thường là cần 4 bytes (với 32-bit) nên hên xui mà bạn sẽ gặp lỗi nếu số lượng phần tử lớn, chữa cháy bằng malloc(n*sizeof(int));
Tóm lại 1 câu: hàm này vô nghĩa! Để hàm này có nghĩa thì bạn phải return con trỏ đó lại:

int *XinCapPhat(int n){
	a = (int*) malloc(n*sizeof(int));
	if(a == NULL){
		printf("Khong du bo nho");
		getch();
		exit(1);
	}
	return a;
}

Còn mấy phần còn lại là OK :smile:
Góp ý lần nữa, bạn pha trộn C và C++ lộn tùm phèo: bạn muốn viết trên C mà lại dùng tham chiếu, còn nếu trên C++ thì không dùng malloc() đâu nha bạn. Khi dùng malloc() rồi thì nhớ free().

1 Like

Nếu đã chia hàm thì bạn phải hình dung:

  • Hàm này cần gì?
  • Hàm này làm gì?
  • Kết quả của hàm này là gì? (Và lấy như thế nào?)

em cảm ơn mọi người nhiều ạ, tại vì em làm theo 1 ví dụ trong sách. Sách viết code y như thế nhưng không hiểu sao lại có lỗi xảy ra

à anh ơi vậy nếu em làm thao tác xin cấp phát bộ nhớ trong hàm main thì vẫn được phải không anh

truyền con trỏ trỏ tới con trỏ cũng được phải ko bác :smile:

  • Có thể do sách sai hoặc em gõ từ trong sách ra sai :joy: Chuyện trong sách có lỗi là ‘chuyện thường ngày ở huyện’, không thể tránh sai sót được.
  • Đúng rồi, nếu em cấp phát trong main thì sẽ không có lỗi.
  • @Mai_Huu: vậy thì được :joy: miễn là đưa con trỏ trỏ tới địa chỉ mà mình mới xin cấp phát là được. Dù sao thì hàm XinCapPhat() cũng không trả về NULL nên dùng return cho lẹ với lại khỏi sợ quên dấu '&' :smile:
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?