30/09/2018, 20:22

Vấn đề chỉ số mảng trong C

Em đang học về mảng trong C, nhưng có một vấn đề không hiểu. Ví dụ khi khai báo:

float a[3];

thì mảng a sẽ gồm 3 phần tử có chỉ số a[0] , a[1] , a[2]. Nhưng sao em nhập giá trị cho a[10] và in ra thì vẫn được.
Mọi người giải thích hộ em. Em xin cảm ơn!

Bé tập Code viết 22:33 ngày 30/09/2018

Đây là một điểm yếu của C (và cả C++),không kiểm soát chặt chẽ biên của mảng.

Trường hợp của bạn, bạn có thể truy xuất ngoài phạm vi của mảng nhưng giá trị đó được gọi là Undefined Behavior, chẳng thể hiện điều gì hết

Khi code người ta thường có điều kiện chặn trước để tránh bị truy xuất vào những phần tử ngoài mảng như vậy.

Chẳng hạn như trong trường hợp của bạn:

if (index <= 2) {
 a[index] = ...; //làm gì đó 
}
Lâm Gia Khang viết 22:25 ngày 30/09/2018

Cảm ơn bạn. Cho mình hỏi là nếu mình dùng phần tử ngoài mảng đó để tính toán thì vẫn được phải không?

Chế Vũ Gia Hy viết 22:24 ngày 30/09/2018

C là ngôn ngữ bâc thấp, nó không ngăn cản bạn làm như thế, cho nên bạn phải chịu rủi ro với những điều minh làm.

Bạn có thể gắn a[10], vì đơn gỉan a[10] tương đương với a + 10*sizeof(float) là vị trí trong stack memory, , tương đương với cách tính index 0 1 2. Vì bạn đã khai báo float a[3], do đó trình biên dịch đã đảm bảo chỗ memory kia tự do.

Ở đây có thể bạn may mắn vì a[10] free ban thử gán a[100000] hay những index cao xem, sẽ hiện lỗi

Bé tập Code viết 22:34 ngày 30/09/2018

Mình chưa hiểu ý bạn lắm. Nếu ý bạn là mảng float a[3]; mà bạn tính toán trên a[3] hay a[4] hay a[255] chẳng hạn thì tuyệt đối không được. Như mình đã nói giá trị đó là Undefined Behavior và nó có thể là bất cứ thứ gì.

Chế Vũ Gia Hy viết 22:26 ngày 30/09/2018

Nếu như bạn gán qúa range của array, bạn có thể phá chính máy tính của mình

Bé tập Code viết 22:38 ngày 30/09/2018

sao lại phá máy tính bạn ???

Chế Vũ Gia Hy viết 22:38 ngày 30/09/2018

vì có thể bạn gán nhầm memory của chương trình khác, néu như có chủ quyền

Bé tập Code viết 22:22 ngày 30/09/2018

Không thể được với những hệ điều hành thời nay bạn nhé, OS bây giờ đều cấp một vùng nhớ ảo cho tất cả các chương trình. Chẳng hạn bạn Lâm Gia Khang dùng Visual Studio để chạy thì cả chương trình của bạn đó chỉ được cung cấp một vùng nhớ ảo xác định thôi, không chương trình nào khác xâm phạm vào. Bạn muốn hack vùng nhớ của chương trình khác thì bạn phải cheat máy tính của bạn bằng những cách khác nhưng đó là cả một câu chuyện dài và nó không liên quan đến việc access ngoài range của mảng mà chúng ta đang bàn

Chế Vũ Gia Hy viết 22:24 ngày 30/09/2018

Mình không biết việc HĐH thời nay đều cấp bộ nhớ ảo cho các chương trình, nếu được ban cho mình link tham khảo. Trước đây mình cũng đã thử gán ngoài range nhiều lần nhưng đều xuất ra lỗi “segmentation fault”. Đó là một cách bảo vệ memory của HĐH, nghĩa là C(C++) cho phép bạn gán nhưng HĐH k cho phép, và lỗi đó chỉ xảy ra khi bạn không có quyền hoặc cố gắng thay đổi vùng read-only memory hoặc của OS

Lâm Gia Khang viết 22:27 ngày 30/09/2018

Ý mình là giống như ví dụ mình nêu ra.

float a[3],c;
a[10]=2;
c=a[10]*2;
printf("c=%f",c);

thì khi đó c vẫn có giá trị xác định là 4 và vẫn in ra màn hình được. Có nghĩa là a[10] vẫn sử dụng được để tính toán dù vượt ngoài mảng???

Bé tập Code viết 22:31 ngày 30/09/2018

Bạn search google là ra ngay ấy mà ^^. Chính xác, Segmentation fault là một trong những minh chứng bạn không có quyền bay ra khỏi vùng nhớ ảo mà bạn được cấp. Đơn giản vậy thôi

Chế Vũ Gia Hy viết 22:31 ngày 30/09/2018

Như BetapCode đã nói đó là Undefined Behaviour, mọi thứ có thể xảy ra, nó có thể hoạt động hôm nay nhưng về lâu dài nó có thể crash, freeze máy của bạn Cho nên đừng sử dụng a[10] để tính toán

Bài liên quan
0