V.4.2 - Tổ chức vùng nhớ của mảng
Như trong phần trên chúng ta đã nói, khi có một định nghĩa mảng thì chương trình biên dịch cấp phát một vùng nhớ 0 có kích thước bằng tổng kích thước của các phần tử trong mảng, các phần tử của mảng xếp tuần tự trong bộ nhớ, phần tử đầu tiên có địa chỉ thấp nhất trong vùng đó, và đây cũng chính là địa chỉ của mảng, phần tử thứ hai của mảng sẽ là ô nhớ kề sát sau (ô nhớ có địa chỉ cao hơn) phần tử thứ nhất,... Ở đây chúng ta nói ô nhớ có thể là 1 byte, 2 byte, 4 byte,.. tùy theo kiểu dữ liệu của các phần tử mảng là gì (tương ứng là 1,2,4,.. byte). Và địa chỉ của ô nhớ là địa chỉ của byte đầu tiên trong các byte đó.
Ví dụ 1: chúng ta định nghĩa mảng A kiểu nguyên:
int A[5];
float X[6];
Chương trình dịch sẽ cấp phát một vùng nhớ 6 × 4 = 24 byte cho mảng X, giả sử rằng vùng nhớ đó có địa chỉ là 200 ( byte đầu tiên có địa chỉ là 200) thì các phần tử của X được cấp phát là địa chỉ của X[0] là 200 (&X[0] = 200), &X[1] = 204,..,&X[5] =216. Với mảng 2 chiều, giả sử mảng D có n dòng, m cột, kiểu int:
int D[n][m]; // n, m là hằng nguyên
Tức là có n×m phần tử kiểu nguyên, như trên chúng ta nói D được xem là mảng có n phần tử, mỗi phần tử lại là một mảng, mảng thành phần này có m phần tử. Như vậy D được cấp phát một vùng nhớ liên tiếp, trong vùng đó có n vùn con cho n phần tử (dòng), trong mỗi vùng con có m ô nhớ (mỗi ô là một phần tử, 2byte). Hay nói cách khác các phần tử của mảng được cấp phát liên tiếp, đầu tiên là m phần tử của hàng 0, sau đó là m phần tử của hàng 1,... Giả sử địa chỉ của mảng D là xxxx thì các phần tử của nó như sau:
D[0] có địa chỉ là xxxx
D[0][0] có địa chỉ là xxxx (&D[0][0] = =xxxx)
D[0][1] có địa chỉ là xxxx + 2 2
D[0][m-1] có địa chỉ là xxxx+2-1 0)
D[1] có địa chỉ là xxxx +2m
D[1][0] có địa chỉ là xxxx +2m 2
D[1][1] có địa chỉ là xxxx + 2m +2 4 ....
D[1][m-1] có địa chỉ là xxxx+2m +2-1 2) ...
Ví dụ: int D[3][4];
Hạn chế số phần tử của mảng
Tuy rằng ngôn ngữ không đưa ra con số cụ thể giới hạn các phần tử của mảng, nhưng kích thước của mảng bị hạn chế bởi các yếu tố sau:
- Các phần tử mảng được cấp phát liên tiếp, trong 1 đoạn bộ nhớ (64kb), do vậy tổng kích thước của mảng ≤ 64kb (số_pt × sizeof(kiểu_mảng) ≤ 65535)
- Kích thước mảng có thể cấp phát phụ thuộc lượng bộ nhớ tự do mà chương trình dịch có thể cấp phát được.
Ví dụ nếu bộ nhớ tự do (trong 1 đoạn) có thể cấp phát còn lại là 100 byte thì nếu là mảng nguyên 1 chiều kiểu int thì kích thước tối đa có thể là 50, với mảng một chiều kiểu float thì chỉ có thể là 25 phần tử,..