01/10/2018, 00:28

Thắc mắc mảng và chuỗi

#include<stdio.h>
int main()
{
	char s[5];
	gets(s);
	puts(s);
	return 0;
}

Tại sao code trên mh chỉ khai báo chuỗi s có 5 ký tự nhưng khi nhập vào 6 hay 7 ký tự nó vẫn hiển thị được vậy mọi người

Người bí ẩn viết 02:45 ngày 01/10/2018

Tại sao code trên mh chỉ khai báo chuỗi s có 5 ký tự nhưng khi nhập vào 6 hay 7 ký tự nó vẫn hiển thị được vậy mọi người

Vậy khi hiển thị ra xong hoặc khi tắt console nó có “bắn” ra cái bảng gì không ?

Nguyễn Văn Công viết 02:30 ngày 01/10/2018

Vậy khi hiển thị ra xong hoặc khi tắt console nó có “bắn” ra cái bảng gì không ?

Hiện thị cái gì bạn. Mh chay thấy nó vẫn bt thế thôi.

Ngô Doãn Tuấn viết 02:29 ngày 01/10/2018

Cái này mình có thể lý giải là do hàm gets mà ra !

Hàm gets đã cũ và nó bị cảnh báo sử dụng trong một số trình dịch mới update!

Bạn hãy thử sử dụng hàm fgets(s,5,sdtin)
Kết quả sẽ đúng như những gì bạn cần !

Văn Thành Trương viết 02:41 ngày 01/10/2018

Bạn ko nên dùng hàm gets trong mọi trường hợp, bạn có thể dùng hàm fgets thay thế, lí do là vì hàm gets ko hề nhận thêm bất kì tham số nào nói về size của chuỗi s, do đó nếu bạn nhập vào một chuỗi dài, tầm 24 kí tự trở lên thì bạn sẽ thấy xuất hiện lỗi segmentation fault.
Lí do nhập tầm 24 kí tự trở lên mới xuất hiện lỗi này là do lúc chạy chương trình, stack sẽ khởi tạo 1 vùng nhớ lớn hơn 5 byte cho chuỗi s, do đó nếu bạn nhập 6 hay 7 hay 20 kí tự thì chương trình vẫn chạy bình thường nhưng nhập nhiều hơn thì khả năng lỗi rất cao.
Đây là đoạn hợp ngữ mình thu được từ chương trình của bạn, bạn ko cần phải hiểu đoạn này, mình sẽ giải thích 1 cách vắn tắt.

subq $24, %rsp
.cfi_def_cfa_offset 32
xorl %eax, %eax
movq %rsp, %rdi
call gets
movq %rsp, %rdi
call puts
xorl %eax, %eax
addq $24, %rsp
.cfi_def_cfa_offset 8
ret

Đoạn code trên tương đương với chương trình của bạn, đại khái thì thay vì khởi tạo chuỗi s chỉ có 5 bytes thì nó cho chuỗi s nhiều hơn 5 bytes do đó lúc bạn nhập 1 chuỗi kí tự tầm 10-15 kí tự thì nó vẫn chạy tốt, nhưng bạn thử nhập 1 câu dài thì sẽ lỗi ngay. Giải pháp là bạn nên dùng fgets như bạn trên kia đã trả lời.

Nguyễn Văn Công viết 02:33 ngày 01/10/2018

Cảm ơn 2 bạn nhé. Nhưng mà ko chỉ hàm gets đâu. Các bạn thử xem code này của mh nhé.
#include<stdio.h>

int main()
{
int i,c[5];
for(i=0;i<7;i++)
scanf("%d",&c[i]);
for(i=0;i<7;i++)
printf("%d ",c[i]);

return 0;

}
Cái này mh chỉ khai báo mảng 5 phần tử nhưng nhập vào 6 hay 7 phần tử nó vẫn hiện ra đc bt. Mh chỉ mới làm quen với C nên cũng chưa hiểu đc bộ nhớ đệm hay bộ nhớ cấp phát nó làm việc thế nào. Thanks.

Nguyễn Hoàng Trung viết 02:37 ngày 01/10/2018

i < 5 chứ bác @_@…

Nguyễn Văn Công viết 02:33 ngày 01/10/2018

i < 5 chứ bác @_@…

i<5 thì mh hỏi làm gì bác. Ý mh muốn hỏi là tại sao khai báo có 5 phần tử mà khi làm đến 6 hay 7 phần tử cũng đc. Vậy thì khai báo bằng 5 mục đích gì?

Doanh Văn Lương viết 02:41 ngày 01/10/2018

trường hợp này là do bạn may mắn vì sau mảng c[5] vẫn còn ô nhớ trống và không có chương trình nào sử dụng ô nhớ đó nên bạn có thể ghi vào đó. nếu mảng mà hệ điều hành cấp phát vừa đủ và ở sau mảng là ô nhớ đang được sử dụng thì sẽ bị lỗi vì mảng đang trỏ đến ô nhớ không được phép sử dụng.

Bài liên quan
0