Thắc mắc về giới hạn của mảng trong C

Em có 1 đoạn code như thế này.

#include <stdio.h>

int main() {
    int a[1];
    a[100] = 1;
    printf("%d", a[100]);
    return 0;
}

Link: http://rextester.com/PHQYD95587

Vấn đề là tại sao em vẫn có thể gán được giá trị cho chỉ mục 100 vậy ạ?
Đúng ra nó phải báo lỗi chứ ạ @@
Em hoang mang quá mấy anh chị :frowning:
Mong mọi người giúp đỡ với ạ.

Khi dùng mảng thường sẽ đi kèm 1 biến lưu size của mảng vì lý do

  • có thể kiểm soát được input và ouput mong muốn
  • tránh dùng vào ô nhớ mà đang được chương trình khác đang dùng -> lỗi
  • tránh dùng vào ô nhớ nằm ngoài phạm vi cấp phát -> nhận được giá trị rác

int a[3];
bộ nhớ sẽ cấp phát cho 3 phân tử như sau, trong đó tên mảng chính là phần tử đầu tiên và bắt đầu đếm từ 0

có nghĩa là đến a3, thì con có a4, a5 … chính là các ô nhớ phía sau, vị trí đếm từ tên mảng, nghĩa là vị trí thứ 0 so với mảng và là vị trí thử 108 trong bộ nhớ -> có thể gán được giá trị cho a[n] phía sau, nhưng trường hợp sau sẽ lỗi

  • ô nhớ a[n] đang được chương trình khác dùng
  • ô nhớ a[n] được gán nằm ngoài phạm vi bộ nhớ
    còn nếu 2 trường hợp trên không xảy ra thì vẫn gán được và sử dụng được
    (ảnh lấy từ bài viết này Mảng một chiều C/C++)

thử 1 chương trình

int a[1];
a[1] = 123;
a[3] = 111;
for (int i = 0; i < 10; i++) cout << a[i] << " ";

kết quả

1 Like

Vậy là mình vẫn có thể sử dụng bộ nhớ nằm ngoài giới hạn mình cho trong một vài trường hợp đúng không ạ?

Vậy nếu mình làm như vậy thì hơi sai sai -> Vậy sao trình biên dịch không báo lỗi ạ? Em cũng không thấy 1 warning nào luôn @@

Bạn chú ý, khi bạn dùng mảng, duyệt mảng để làm gì đó mà bị nhầm chỉ số mảng, vượt ra khỏi giới hạn, thì hay có thông báo lỗi có thanh tiến trình chạy ngang màu xanh đó, hoặc có khi nhận được giá trị rác -> kết quả sai

1 Like

C không quản lý bounds (rìa) của array nên bạn có thể index ra ngoài giới hạn mảng, compiler sẽ không check, nhưng đây là việc không nên làm bởi bạn đang cố viết ra ngoài vùng nhớ được cho phép và bạn có thể sẽ vô tình viết đè lên bộ nhớ mà chương trình khác đang dùng (khi này OS sẽ cản lại bằng cách quăng segfault).

2 Likes

C/C++ đều thế cả :joy:
Compiler mingw g++,gcc hay compiler của VS đều không bắt lỗi này

1 Like

Chúng chỉ bắt tốt lỗi cú pháp. Đây không phải lỗi cú pháp thì nó không bắt được.

Lỗi cú pháp thì như sai chính tả nên dễ bắt. Lỗi này giống như lỗi nội dung thường chỉ bắt được khi chạy chương trình.

3 Likes

Standard không nói gì về việc kiểm tra boundary của mảng nên cũng không lạ khi các compilers phổ biến đều không check. Còn thớt code C nên mình đề cập riêng C thôi ấy mà :blush:


Edit: “mảng” ở đây ý mình là mảng thuần, kiểu char c[6];. Những thứ như std::vector<>, std::deque<>, std::array<>… đều có boundary check.

3 Likes

Cám ơn mọi người đã giải đáp :blush:

C/C++ là đúng kiểu Sức mạnh càng lớn trách nhiệm càng cao đấy. :sweat_smile:

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