“Bộ nhớ được cấp phát tại thời điểm biên dịch” thực sự có nghĩa là gì?

168
Talha Sayed 2014-01-26 02:24.

Trong các ngôn ngữ lập trình như C và C ++, người ta thường đề cập đến cấp phát bộ nhớ tĩnh và động. Tôi hiểu khái niệm nhưng cụm từ "Tất cả bộ nhớ đã được cấp phát (dành riêng) trong thời gian biên dịch" luôn khiến tôi bối rối.

Theo tôi hiểu, quá trình biên dịch sẽ chuyển đổi mã C / C ++ cấp cao sang ngôn ngữ máy và xuất ra một tệp thực thi. Bộ nhớ được "cấp phát" như thế nào trong một tệp đã biên dịch? Không phải lúc nào bộ nhớ cũng được phân bổ trong RAM với tất cả các công cụ quản lý bộ nhớ ảo?

Không phải cấp phát bộ nhớ theo định nghĩa là một khái niệm thời gian chạy?

Nếu tôi tạo một biến được cấp phát tĩnh 1KB trong mã C / C ++ của mình, thì biến đó có làm tăng kích thước của tệp thực thi lên cùng một lượng không?

Đây là một trong những trang mà cụm từ được sử dụng với tiêu đề "Phân bổ tĩnh".

Quay lại kiến ​​thức cơ bản: Phân bổ bộ nhớ, xem lại lịch sử

13 answers

190
Manu343726 2014-01-26 02:33.

Bộ nhớ được cấp phát tại thời điểm biên dịch có nghĩa là trình biên dịch giải quyết tại thời điểm biên dịch nơi một số thứ nhất định sẽ được cấp phát bên trong bản đồ bộ nhớ tiến trình.

Ví dụ: hãy xem xét một mảng toàn cục:

int array[100];

Tại thời điểm biên dịch, trình biên dịch biết kích thước của mảng và kích thước của an int, vì vậy nó biết toàn bộ kích thước của mảng tại thời điểm biên dịch. Ngoài ra, một biến toàn cục có thời lượng lưu trữ tĩnh theo mặc định: nó được cấp phát trong vùng bộ nhớ tĩnh của không gian bộ nhớ tiến trình (phần .data / .bss). Với thông tin đó, trình biên dịch quyết định trong quá trình biên dịch, mảng sẽ ở địa chỉ nào của vùng bộ nhớ tĩnh đó .

Tất nhiên địa chỉ bộ nhớ đó là địa chỉ ảo. Chương trình giả định rằng nó có toàn bộ không gian bộ nhớ của riêng nó (Từ 0x00000000 đến 0xFFFFFFFF chẳng hạn). Đó là lý do tại sao trình biên dịch có thể thực hiện các giả định như "Được rồi, mảng sẽ ở địa chỉ 0x00A33211". Trong thời gian chạy, địa chỉ được MMU và OS dịch sang địa chỉ thực / phần cứng.

Những thứ lưu trữ tĩnh được khởi tạo giá trị hơi khác một chút. Ví dụ:

int array[] = { 1 , 2 , 3 , 4 };

Trong ví dụ đầu tiên của chúng tôi, trình biên dịch chỉ quyết định nơi mảng sẽ được cấp phát, lưu trữ thông tin đó trong tệp thực thi.
Trong trường hợp những thứ được khởi tạo giá trị, trình biên dịch cũng sẽ đưa giá trị ban đầu của mảng vào tệp thực thi và thêm mã cho trình nạp chương trình biết rằng sau khi cấp phát mảng khi bắt đầu chương trình, mảng sẽ được lấp đầy bằng các giá trị này.

Dưới đây là hai ví dụ về hợp ngữ được tạo bởi trình biên dịch (GCC4.8.1 với mục tiêu x86):

Mã C ++:

int a[4];
int b[] = { 1 , 2 , 3 , 4 };

int main()
{}

Đầu ra lắp ráp:

a:
    .zero   16
b:
    .long   1
    .long   2
    .long   3
    .long   4
main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $0, %eax
    popq    %rbp
    ret

Như bạn có thể thấy, các giá trị được đưa trực tiếp vào assembly. Trong mảng a, trình biên dịch tạo ra một khởi tạo bằng không 16 byte, bởi vì Tiêu chuẩn nói rằng những thứ được lưu trữ tĩnh nên được khởi tạo bằng 0 theo mặc định:

8.5.9 (Bộ khởi tạo) [Lưu ý]:
Mọi đối tượng của thời gian lưu trữ tĩnh đều được khởi tạo bằng 0 khi khởi động chương trình trước khi bất kỳ quá trình khởi tạo nào khác diễn ra. Trong một số trường hợp, việc khởi tạo bổ sung được thực hiện sau đó.

Tôi luôn đề nghị mọi người tháo rời mã của họ để xem trình biên dịch thực sự làm gì với mã C ++. Điều này áp dụng từ các lớp / thời lượng lưu trữ (như câu hỏi này) đến tối ưu hóa trình biên dịch nâng cao. Bạn có thể hướng dẫn trình biên dịch của mình tạo assembly, nhưng có những công cụ tuyệt vời để thực hiện việc này trên Internet một cách thân thiện. Yêu thích của tôi là GCC Explorer .

27
mah 2014-01-26 02:32.

Bộ nhớ được phân bổ tại thời gian biên dịch chỉ có nghĩa là sẽ không có phân bổ thêm vào thời gian chạy - không có cuộc gọi đến malloc, newhoặc các phương pháp phân bổ động khác. Bạn sẽ có một lượng sử dụng bộ nhớ cố định ngay cả khi bạn không cần tất cả bộ nhớ đó.

Không phải cấp phát bộ nhớ theo định nghĩa là một khái niệm thời gian chạy?

Bộ nhớ không được sử dụng trước thời gian chạy, nhưng ngay trước khi thực thi bắt đầu cấp phát sẽ được hệ thống xử lý.

Nếu tôi tạo một biến được cấp phát tĩnh 1KB trong mã C / C ++ của mình, thì biến đó có làm tăng kích thước của tệp thực thi lên cùng một lượng không?

Chỉ cần khai báo static sẽ không làm tăng kích thước tệp thực thi của bạn quá vài byte. Khai báo nó với một giá trị ban đầu khác 0 sẽ (để giữ giá trị ban đầu đó). Thay vào đó, trình liên kết chỉ cần thêm lượng 1KB này vào yêu cầu bộ nhớ mà trình tải của hệ thống tạo cho bạn ngay trước khi thực thi.

23
fede1024 2014-01-26 02:34.

Bộ nhớ được cấp phát trong thời gian biên dịch có nghĩa là khi bạn tải chương trình, một số phần của bộ nhớ sẽ được cấp phát ngay lập tức và kích thước và vị trí (tương đối) của phân bổ này được xác định tại thời điểm biên dịch.

char a[32];
char b;
char c;

3 biến đó được "cấp phát tại thời điểm biên dịch", có nghĩa là trình biên dịch tính toán kích thước của chúng (được cố định) tại thời điểm biên dịch. Biến asẽ là một phần bù trong bộ nhớ, giả sử, trỏ đến địa chỉ 0, bsẽ trỏ đến địa chỉ 33 và c34 (giả sử không có tối ưu hóa căn chỉnh). Vì vậy, việc phân bổ 1Kb dữ liệu tĩnh sẽ không làm tăng kích thước mã của bạn , vì nó sẽ chỉ thay đổi một phần bù bên trong nó. Không gian thực tế sẽ được phân bổ tại thời điểm tải .

Việc cấp phát bộ nhớ thực luôn diễn ra trong thời gian chạy, vì hạt nhân cần theo dõi nó và cập nhật cấu trúc dữ liệu bên trong của nó (lượng bộ nhớ được cấp cho mỗi tiến trình, các trang, v.v.). Sự khác biệt là trình biên dịch đã biết kích thước của từng dữ liệu bạn sẽ sử dụng và điều này được cấp phát ngay sau khi chương trình của bạn được thực thi.

Cũng nên nhớ rằng chúng ta đang nói về địa chỉ tương đối . Địa chỉ thực nơi biến sẽ được đặt sẽ khác. Tại thời điểm tải, hạt nhân sẽ dự trữ một số bộ nhớ cho quá trình, giả sử tại địa chỉ x, và tất cả các địa chỉ được mã hóa cứng chứa trong tệp thực thi sẽ được tăng dần theo xbyte, vì vậy biến đó atrong ví dụ sẽ ở địa chỉ x, b là địa chỉ x+33và Sớm.

17
Elias Van Ootegem 2014-01-26 02:45.

Việc thêm các biến trên ngăn xếp chiếm N byte không (nhất thiết) làm tăng kích thước của thùng lên N byte. Trên thực tế, nó sẽ thêm trừ một vài byte trong hầu hết thời gian.
Hãy bắt đầu với một ví dụ về cách thêm 1000 ký tự vào mã của bạn sẽ làm tăng kích thước của thùng theo kiểu tuyến tính.

Nếu 1k là một chuỗi, của một nghìn ký tự, được khai báo như vậy

const char *c_string = "Here goes a thousand chars...999";//implicit \0 at end

và sau đó vim your_compiled_bin, bạn thực sự có thể thấy chuỗi đó trong thùng ở đâu đó. Trong trường hợp đó, có: tệp thực thi sẽ lớn hơn 1 k, vì nó chứa đầy đủ chuỗi.
Tuy nhiên, nếu bạn phân bổ một mảng ints, chars hoặc longs trên ngăn xếp và gán nó trong một vòng lặp, thì một cái gì đó dọc theo những dòng này

int big_arr[1000];
for (int i=0;i<1000;++i) big_arr[i] = some_computation_func(i);

sau đó, không: nó sẽ không tăng thùng rác ... bởi 1000*sizeof(int)
Phân bổ tại thời điểm biên dịch có nghĩa là bây giờ bạn đã hiểu nó có nghĩa là gì (dựa trên nhận xét của bạn): thùng biên dịch chứa thông tin mà hệ thống yêu cầu để biết bao nhiêu bộ nhớ chức năng / khối nào sẽ cần khi nó được thực thi, cùng với thông tin về kích thước ngăn xếp mà ứng dụng của bạn yêu cầu. Đó là những gì hệ thống sẽ phân bổ khi nó thực thi bin của bạn và chương trình của bạn trở thành một quá trình (tốt, việc thực thi bin của bạn là quá trình ... tốt, bạn hiểu những gì tôi đang nói).
Tất nhiên, tôi không vẽ toàn bộ bức tranh ở đây: Thùng chứa thông tin về việc thùng thực sự sẽ cần một ngăn xếp lớn như thế nào. Dựa trên thông tin này (trong số những thứ khác), hệ thống sẽ dự trữ một phần bộ nhớ, được gọi là ngăn xếp, để chương trình có được quyền thống trị tự do. Bộ nhớ ngăn xếp vẫn được hệ thống cấp phát, khi quá trình (kết quả của thùng của bạn đang được thực thi) được bắt đầu. Sau đó, quá trình sẽ quản lý bộ nhớ ngăn xếp cho bạn. Khi một hàm hoặc vòng lặp (bất kỳ loại khối nào) được gọi / được thực thi, các biến cục bộ của khối đó sẽ được đẩy vào ngăn xếp và chúng bị xóa (bộ nhớ ngăn xếp được "giải phóng" có thể nói) để được sử dụng bởi khác chức năng / khối. Vì vậy, việc khai báo int some_array[100]sẽ chỉ thêm một vài byte thông tin bổ sung vào thùng, điều đó cho hệ thống biết rằng hàm X sẽ yêu cầu 100*sizeof(int)+ thêm một số không gian lưu trữ sách.

16
supercat 2014-01-26 08:38.

Trên nhiều nền tảng, tất cả các phân bổ toàn cục hoặc tĩnh trong mỗi mô-đun sẽ được trình biên dịch hợp nhất thành ba hoặc ít hơn các phân bổ tổng hợp (một cho dữ liệu chưa khởi tạo (thường được gọi là "bss"), một cho dữ liệu có thể ghi được khởi tạo (thường được gọi là "dữ liệu") ), và một cho dữ liệu không đổi ("const")), và tất cả các phân bổ toàn cục hoặc tĩnh của mỗi loại trong một chương trình sẽ được trình liên kết hợp nhất thành một toàn cục cho mỗi loại. Ví dụ: giả sử intlà bốn byte, một mô-đun có phần sau là phân bổ tĩnh duy nhất của nó:

int a;
const int b[6] = {1,2,3,4,5,6};
char c[200];
const int d = 23;
int e[4] = {1,2,3,4};
int f;

nó sẽ cho trình liên kết biết rằng nó cần 208 byte cho bss, 16 byte cho "dữ liệu" và 28 byte cho "const". Hơn nữa, bất kỳ tham chiếu nào đến một biến sẽ được thay thế bằng bộ chọn vùng và bù đắp, vì vậy a, b, c, d và e, sẽ được thay thế bằng bss + 0, const + 0, bss + 4, const + 24, data +0, hoặc bss + 204, tương ứng.

Khi một chương trình được liên kết, tất cả các vùng bss từ tất cả các mô-đun sẽ được nối với nhau; tương tự như vậy các vùng dữ liệu và const. Đối với mỗi mô-đun, địa chỉ của bất kỳ biến tương đối bss nào sẽ được tăng lên theo kích thước của tất cả các vùng bss của mô-đun trước đó (một lần nữa, tương tự như vậy với dữ liệu và const). Do đó, khi trình liên kết được thực hiện, bất kỳ chương trình nào cũng sẽ có một cấp phát bss, một cấp phát dữ liệu và một cấp phát const.

Khi một chương trình được tải, một trong bốn điều thường xảy ra tùy thuộc vào nền tảng:

  1. Tập tin thực thi sẽ cho biết nó cần bao nhiêu byte cho mỗi loại dữ liệu và - cho vùng dữ liệu khởi tạo, nơi có thể tìm thấy nội dung ban đầu. Nó cũng sẽ bao gồm một danh sách tất cả các hướng dẫn sử dụng địa chỉ bss-, data- hoặc const- tương đối. Hệ điều hành hoặc bộ tải sẽ phân bổ lượng không gian thích hợp cho từng khu vực và sau đó thêm địa chỉ bắt đầu của khu vực đó vào từng lệnh cần nó.

  2. Hệ điều hành sẽ phân bổ một phần bộ nhớ để chứa cả ba loại dữ liệu và cung cấp cho ứng dụng một con trỏ đến phần bộ nhớ đó. Bất kỳ mã nào sử dụng dữ liệu tĩnh hoặc toàn cục sẽ tham chiếu đến nó liên quan đến con trỏ đó (trong nhiều trường hợp, con trỏ sẽ được lưu trữ trong một thanh ghi cho thời gian tồn tại của ứng dụng).

  3. Ban đầu, hệ điều hành sẽ không cấp phát bất kỳ bộ nhớ nào cho ứng dụng, ngoại trừ những gì chứa mã nhị phân của nó, nhưng điều đầu tiên ứng dụng làm sẽ là yêu cầu một phân bổ phù hợp từ hệ điều hành, mà nó sẽ mãi mãi giữ trong một thanh ghi.

  4. Hệ điều hành ban đầu sẽ không phân bổ không gian cho ứng dụng, nhưng ứng dụng sẽ yêu cầu phân bổ thích hợp khi khởi động (như trên). Ứng dụng sẽ bao gồm một danh sách các hướng dẫn với các địa chỉ cần được cập nhật để phản ánh vị trí bộ nhớ được cấp phát (như với kiểu đầu tiên), nhưng thay vì để ứng dụng được vá bởi bộ tải hệ điều hành, ứng dụng sẽ bao gồm đủ mã để tự vá. .

Cả bốn cách tiếp cận đều có ưu điểm và nhược điểm. Tuy nhiên, trong mọi trường hợp, trình biên dịch sẽ hợp nhất một số lượng tùy ý các biến tĩnh vào một số lượng nhỏ các yêu cầu bộ nhớ cố định và trình liên kết sẽ hợp nhất tất cả các biến đó thành một số lượng nhỏ các phân bổ hợp nhất. Mặc dù một ứng dụng sẽ phải nhận một phần bộ nhớ từ hệ điều hành hoặc trình tải, nhưng chính trình biên dịch và trình liên kết chịu trách nhiệm phân bổ các phần riêng lẻ từ phần lớn đó cho tất cả các biến riêng lẻ cần nó.

13
Jules 2014-01-26 10:06.

Cốt lõi của câu hỏi của bạn là: "Bộ nhớ được" cấp phát "như thế nào trong một tệp đã biên dịch? Không phải bộ nhớ luôn được cấp phát trong RAM với tất cả các công cụ quản lý bộ nhớ ảo? Không phải định nghĩa cấp phát bộ nhớ là khái niệm thời gian chạy?"

Tôi nghĩ vấn đề là có hai khái niệm khác nhau liên quan đến cấp phát bộ nhớ. Về cơ bản, cấp phát bộ nhớ là quá trình mà chúng ta nói "mục dữ liệu này được lưu trữ trong phần bộ nhớ cụ thể này". Trong một hệ thống máy tính hiện đại, điều này bao gồm một quá trình gồm hai bước:

  • Một số hệ thống được sử dụng để quyết định địa chỉ ảo nơi mục sẽ được lưu trữ
  • Địa chỉ ảo được ánh xạ tới địa chỉ thực

Quá trình thứ hai hoàn toàn là thời gian chạy, nhưng quá trình trước có thể được thực hiện tại thời điểm biên dịch, nếu dữ liệu có kích thước đã biết và yêu cầu một số lượng cố định trong số chúng. Về cơ bản đây là cách nó hoạt động:

  • Trình biên dịch thấy tệp nguồn chứa một dòng trông giống như sau:

    int c;
    
  • Nó tạo ra đầu ra cho trình hợp dịch chỉ thị nó dành bộ nhớ cho biến 'c'. Cái này có thể trông như thế này:

    global _c
    section .bss
    _c: resb 4
    
  • Khi trình hợp dịch chạy, nó sẽ giữ một bộ đếm theo dõi hiệu số của từng mục từ khi bắt đầu một 'đoạn' bộ nhớ (hoặc 'phần'). Điều này giống như các phần của một 'cấu trúc' rất lớn chứa mọi thứ trong toàn bộ tệp mà nó không có bất kỳ bộ nhớ thực tế nào được cấp phát vào lúc này và có thể ở bất cứ đâu. Nó ghi chú trong một bảng _ccó một độ lệch cụ thể (ví dụ 510 byte tính từ đầu đoạn) và sau đó tăng bộ đếm của nó lên 4, vì vậy biến tiếp theo sẽ ở (ví dụ) 514 byte. Đối với bất kỳ mã nào cần địa chỉ _c, nó chỉ cần đặt 510 vào tệp đầu ra và thêm một lưu ý rằng đầu ra cần địa chỉ của phân đoạn có chứa _cthêm vào nó sau này.

  • Trình liên kết lấy tất cả các tệp đầu ra của trình hợp dịch và kiểm tra chúng. Nó xác định một địa chỉ cho mỗi phân đoạn để chúng không trùng lặp và thêm các hiệu số cần thiết để các hướng dẫn vẫn tham chiếu đến các mục dữ liệu chính xác. Trong trường hợp bộ nhớ chưa được khởi tạo giống như bị chiếm bởi c(trình hợp dịch được thông báo rằng bộ nhớ sẽ không được khởi tạo bởi thực tế là trình biên dịch đặt nó trong phân đoạn '.bss', là tên dành riêng cho bộ nhớ chưa được khởi tạo), nó bao gồm trường tiêu đề trong đầu ra của nó cho hệ điều hành biết số lượng cần được dự trữ. Nó có thể được di dời (và thường là như vậy) nhưng thường được thiết kế để tải hiệu quả hơn tại một địa chỉ bộ nhớ cụ thể và hệ điều hành sẽ cố gắng tải nó tại địa chỉ này. Tại thời điểm này, chúng tôi có một ý tưởng khá tốt về địa chỉ ảo sẽ được sử dụng bởi c.

  • Địa chỉ vật lý sẽ không thực sự được xác định cho đến khi chương trình đang chạy. Tuy nhiên, từ quan điểm của lập trình viên, địa chỉ vật lý thực sự không liên quan - chúng tôi thậm chí sẽ không bao giờ tìm hiểu nó là gì, bởi vì hệ điều hành thường không bận tâm đến bất kỳ ai, nó có thể thay đổi thường xuyên (ngay cả khi chương trình đang chạy), và Mục đích chính của Hệ điều hành là để trừu tượng hóa điều này.

9
meaning-matters 2014-01-26 02:30.

Một tệp thực thi mô tả không gian nào cần cấp phát cho các biến tĩnh. Việc phân bổ này được thực hiện bởi hệ thống, khi bạn chạy tệp thực thi. Vì vậy, biến tĩnh 1kB của bạn sẽ không tăng kích thước của tệp thực thi với 1kB:

static char[1024];

Tất nhiên trừ khi bạn chỉ định một trình khởi tạo:

static char[1024] = { 1, 2, 3, 4, ... };

Vì vậy, ngoài 'ngôn ngữ máy' (tức là các lệnh CPU), một tệp thực thi còn chứa mô tả về bố cục bộ nhớ được yêu cầu.

5
exebook 2014-01-26 08:11.

Bộ nhớ có thể được cấp phát theo nhiều cách:

  • trong đống ứng dụng (toàn bộ đống được hệ điều hành phân bổ cho ứng dụng của bạn khi chương trình bắt đầu)
  • trong đống hệ điều hành (vì vậy bạn có thể lấy nhiều hơn và nhiều hơn nữa)
  • trong đống được kiểm soát của bộ thu gom rác (giống như cả hai ở trên)
  • trên ngăn xếp (vì vậy bạn có thể nhận được tràn ngăn xếp)
  • được dành riêng trong phân đoạn mã / dữ liệu của tệp nhị phân của bạn (có thể thực thi)
  • ở nơi xa (tệp, mạng - và bạn nhận được một chốt không phải là con trỏ tới bộ nhớ đó)

Bây giờ câu hỏi của bạn là "bộ nhớ được cấp phát tại thời điểm biên dịch" là gì. Chắc chắn đó chỉ là một câu nói không chính xác, được cho là đề cập đến phân bổ phân đoạn nhị phân hoặc phân bổ ngăn xếp, hoặc trong một số trường hợp, thậm chí là phân bổ đống, nhưng trong trường hợp đó phân bổ bị ẩn khỏi mắt của lập trình viên bởi lệnh gọi hàm tạo vô hình. Hoặc có thể người nói điều đó chỉ muốn nói rằng bộ nhớ không được cấp phát trên heap, nhưng không biết về cấp phát ngăn xếp hoặc phân đoạn. (Hoặc không muốn đi vào loại chi tiết đó).

Nhưng trong hầu hết các trường hợp, người ta chỉ muốn nói rằng lượng bộ nhớ được cấp phát đã được biết trước tại thời điểm biên dịch .

Kích thước nhị phân sẽ chỉ thay đổi khi bộ nhớ được dành riêng trong mã hoặc phân đoạn dữ liệu của ứng dụng của bạn.

4
Yves Daoust 2014-01-26 04:10.

Bạn đúng rồi. Bộ nhớ thực sự được cấp phát (phân trang) tại thời điểm tải, tức là khi tệp thực thi được đưa vào bộ nhớ (ảo). Bộ nhớ cũng có thể được khởi tạo vào thời điểm đó. Trình biên dịch chỉ tạo một bản đồ bộ nhớ. [Nhân tiện, không gian ngăn xếp và ngăn xếp cũng được phân bổ tại thời điểm tải!]

2
jmoreno 2014-01-26 10:45.

Tôi nghĩ bạn cần phải lùi lại một chút. Bộ nhớ được cấp phát tại thời điểm biên dịch .... Điều đó có nghĩa là gì? Nó có thể có nghĩa là bộ nhớ trên các chip chưa được sản xuất, cho các máy tính chưa được thiết kế, bằng cách nào đó đang được dự trữ? Không, du hành thời gian, không có trình biên dịch nào có thể thao túng vũ trụ.

Vì vậy, nó phải có nghĩa là trình biên dịch tạo ra các lệnh để cấp phát bộ nhớ đó bằng cách nào đó trong thời gian chạy. Nhưng nếu bạn nhìn vào nó từ góc độ bên phải, trình biên dịch tạo ra tất cả các hướng dẫn, vì vậy sự khác biệt có thể là gì. Sự khác biệt là trình biên dịch quyết định và trong thời gian chạy, mã của bạn không thể thay đổi hoặc sửa đổi các quyết định của nó. Nếu nó quyết định nó cần 50 byte tại thời điểm biên dịch, thì trong thời gian chạy, bạn không thể khiến nó quyết định phân bổ 60 - quyết định đó đã được thực hiện.

2
Engineer 2014-01-26 11:48.

Nếu bạn học lập trình hợp ngữ, bạn sẽ thấy rằng bạn phải tạo ra các phân đoạn cho dữ liệu, ngăn xếp và mã, v.v. Phân đoạn dữ liệu là nơi chứa các chuỗi và số của bạn. Đoạn mã là nơi mã của bạn tồn tại. Các phân đoạn này được xây dựng trong chương trình thực thi. Tất nhiên kích thước ngăn xếp cũng quan trọng ... bạn sẽ không muốn bị tràn ngăn xếp !

Vì vậy, nếu phân đoạn dữ liệu của bạn là 500 byte, chương trình của bạn có vùng 500 byte. Nếu bạn thay đổi đoạn dữ liệu thành 1500 byte, kích thước của chương trình sẽ lớn hơn 1000 byte. Dữ liệu được tập hợp vào chương trình thực tế.

Đây là những gì đang diễn ra khi bạn biên dịch các ngôn ngữ cấp cao hơn. Vùng dữ liệu thực tế được cấp phát khi nó được biên dịch thành một chương trình thực thi, làm tăng kích thước của chương trình. Chương trình cũng có thể yêu cầu bộ nhớ khi đang di chuyển và đây là bộ nhớ động. Bạn có thể yêu cầu bộ nhớ từ RAM và CPU sẽ cung cấp cho bạn để sử dụng, bạn có thể loại bỏ nó và bộ thu gom rác của bạn sẽ giải phóng nó trở lại CPU. Nó thậm chí có thể được đổi sang đĩa cứng, nếu cần, bởi một trình quản lý bộ nhớ tốt. Những tính năng này là những gì ngôn ngữ cấp cao cung cấp cho bạn.

2
user3258051 2014-02-01 23:59.

Tôi muốn giải thích những khái niệm này với sự trợ giúp của một vài sơ đồ.

Điều này đúng là chắc chắn không thể cấp phát bộ nhớ tại thời điểm biên dịch. Nhưng thực tế thì điều gì sẽ xảy ra tại thời điểm biên dịch.

Đây là lời giải thích. Ví dụ, một chương trình có bốn biến x, y, z và k. Bây giờ, tại thời điểm biên dịch, nó chỉ đơn giản là tạo một bản đồ bộ nhớ, nơi vị trí của các biến này so với nhau được xác định. Sơ đồ này sẽ minh họa rõ hơn.

Bây giờ hãy tưởng tượng, không có chương trình nào đang chạy trong bộ nhớ. Điều này tôi hiển thị bằng một hình chữ nhật trống lớn.

Tiếp theo, phiên bản đầu tiên của chương trình này được thực thi. Bạn có thể hình dung nó như sau. Đây là thời điểm bộ nhớ thực sự được cấp phát.

Khi phiên bản thứ hai của chương trình này đang chạy, bộ nhớ sẽ trông như sau.

Và thứ ba ..

Vv và Vv.

Tôi hy vọng hình dung này giải thích tốt khái niệm này.

1
user6882413 2019-11-25 11:18.

Có một lời giải thích rất hay được đưa ra trong câu trả lời được chấp nhận. Đề phòng trường hợp tôi sẽ đăng liên kết mà tôi thấy hữu ích. https://www.tenouk.com/ModuleW.html

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Desiree Rogers, trái, và Cheryl Mayberry McKissack Chuyển sang, Fenty Beauty và Pat McGrath, có một đế chế làm đẹp mới do phụ nữ làm chủ đang trỗi dậy. Sau thương vụ mua lại mỹ phẩm Black Opal vào tháng 9, đội ngũ quyền lực của Giám đốc điều hành công ty Desiree Rogers và Chủ tịch Cheryl Mayberry McKissack đã thông báo mua lại thương hiệu làm đẹp tiên phong Fashion Fair từ người sáng lập Johnson Publishing Company (JPC).

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Đối với những người có quá nhiều thời gian, tiệc tiết lộ giới tính là một cách thú vị để không cần áp đặt những định kiến ​​hạn chế lên thai nhi trước một đối tượng bạn bè giả vờ quan tâm một cách lịch sự. Tuy nhiên, việc chỉ dựa vào những chiếc bánh nướng có màu nhân tạo để biểu thị một tiếng hoo-ha hoặc một đứa trẻ đi tè đã trở nên xa xỉ trong các bậc cha mẹ trên Instagram.

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Hôm thứ Tư, cựu Bộ trưởng An ninh Nội địa Kirstjen Nielsen vì một lý do nào đó đã được đưa ra một diễn đàn để phát biểu tại Hội nghị thượng đỉnh Những người phụ nữ quyền lực nhất của Fortune. Và có thể đoán trước được, người phụ nữ giám sát các nỗ lực (đang diễn ra) của chính quyền Trump nhằm chia cắt các gia đình ở biên giới đã sử dụng thời gian của mình như một cơ hội để tự bảo vệ mình và tự nhận mình là người — và hãy hít thở sâu ở đây — “đã nói sự thật với quyền lực.

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Vì thế hệ mới nhất của chiếc xe điều chỉnh được yêu thích trên thế giới hiện đã có mặt tại đây, nên chỉ có điều kiện là Toyota Racing Development sẽ đưa phiên bản Supra thế hệ thứ năm sửa đổi của riêng mình đến SEMA vào tháng tới. Toyota đã cho chúng tôi một gợi ý về những gì sẽ xảy ra trong tuần này: một chiếc Concept GR Supra 3000GT hiện đại.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language