2015-09-02 11 views
6

Tôi đã gặp phải hiện tượng kỳ lạ trong C mà tôi cần ai đó giải thích. Tôi có mã dưới đây với 2 mảng phần tử đơn lẻ làm biến toàn cục. Tôi đang in địa chỉ bộ nhớ của phần tử thứ nhất và thứ hai của mỗi mảng (lưu ý rằng mảng được xác định là chỉ có 1 phần tử):Phân bổ bộ nhớ mảng trong C phụ thuộc vào quy ước đặt tên?

#include <stdio.h> 

int a1[1]; 
int a2[1]; 

int main(void) { 

    a1[0] = 100; 
    a2[0] = 200; 

    printf("%d\n", &a1[0]); 
    printf("%d\n", &a1[1]); 
    printf("%d\n", &a2[0]); 
    printf("%d\n", &a2[1]); 
} 

Điều này cho kết quả sau. Lưu ý rằng C được phân bổ một khối bộ nhớ tiếp giáp với mảng a2 ngay sau khi a1 (do đó địa chỉ của a1 [1] và a2 [0] là giống nhau):

4223424 
4223428 
4223428 
4223432 

Tuy nhiên, một cái gì đó kỳ diệu xảy ra khi tôi thay đổi tên của các mảng. Tôi đã thêm "zzz" làm tiền tố cho cả hai mảng như dưới đây.

#include <stdio.h> 

int zzza1[1]; 
int zzza2[1]; 

int main(void) { 

    zzza1[0] = 100; 
    zzza2[0] = 200; 

    printf("%d\n", &zzza1[0]); 
    printf("%d\n", &zzza1[1]); 
    printf("%d\n", &zzza2[0]); 
    printf("%d\n", &zzza2[1]); 
} 

Sau khi chạy đoạn mã này bạn có thể nhìn thấy từ đầu ra sau đây là bộ nhớ được phân bổ cho các zzza2 mảng đầu tiên và sau đó cho zzza1 (& a2 [1] = & a1 [0]):

4223428 
4223432 
4223424 
4223428 

Tôi đã thử nghiệm mã ở trên với nhiều kích thước mảng (2,4,8) trong các máy khác nhau tại các thời điểm khác nhau và có cùng đầu ra sao cho nó không phải là trùng hợp ngẫu nhiên. Điều này không xảy ra khi tôi xác định các biến trong hàm main() làm biến cục bộ.

Dường như C đang cấp phát bộ nhớ dựa trên tên chúng tôi cung cấp cho các mảng. Thứ nhất, tại sao C phân bổ các khối tiếp giáp với các mảng toàn cục khác nhau mỗi lần? Thứ hai, khi tôi thêm tiền tố, tại sao thứ tự phân bổ bộ nhớ thay đổi?

Hy vọng điều này sẽ không làm phiền mọi người vì nó có tôi ... Cảm ơn sự giúp đỡ của bạn trước!

+4

Chuỗi công cụ (trình liên kết) có ít hoặc nhiều hơn để đặt các đối tượng tại bất kỳ địa chỉ nào mà nó muốn. Có lẽ tên của các đối tượng đi vào một số loại cấu trúc dữ liệu dựa trên một băm của tên và điều đó ảnh hưởng đến thứ tự bố trí? Ai biết? Xem http://stackoverflow.com/questions/4575697/unexpected-output-from-bubblesort-program-with-msvc-vs-tcc/4577565#4577565 cho một tình huống khác mà tên biến ảnh hưởng đến bố cục biến (bởi trình biên dịch thay vì trình liên kết). –

+0

Tôi tò mò muốn biết kết quả là gì với a2 [] được khai báo trước a1 []. Nếu nó giống như thử nghiệm đầu tiên của bạn, tôi đoán là trình biên dịch tham chiếu biến trong một số loại bảng băm và tạo mã đọc tuần tự. Và tất cả các trình biên dịch đều sử dụng cùng một thuật toán băm. –

+0

Dù sao, bạn không nên đưa ra bất kỳ giả định nào về cách các biến được bố trí trong bộ nhớ. –

Trả lời

1

Thứ nhất, tại sao C phân bổ các khối tiếp giáp cho các mảng toàn cầu khác nhau?

Vì một khối liền kề có hiệu quả hơn và dễ triển khai hơn. Nếu ứng dụng phân bổ các biến toàn cầu ở các khối bộ nhớ khác nhau, nó có ít nhất một trong các hạn chế tiếp theo:

  1. Bộ nhớ bị xóa giữa các khối.
  2. Phân bổ bộ nhớ phức tạp khi bắt đầu.

Vì vậy, chuỗi công cụ cố gắng phân bổ tất cả các biến toàn cầu tại một khối bộ nhớ liền kề nhau.