2009-07-23 22 views
65

Nếu tôi khai báo cấu trúc dữ liệu trên toàn cầu trong ứng dụng C++, nó có sử dụng bộ nhớ ngăn xếp hoặc bộ nhớ heap không?Quản lý bộ nhớ toàn cầu trong C++ trong ngăn xếp hoặc đống?

Đối với ví dụ

struct AAA 
{ 

.../.../. 
../../.. 
}arr[59652323]; 
+1

cũng vậy, sự khác nhau giữa biến toàn cầu và biến tĩnh (trong hàm). Họ phải sống cho cuộc đời của chương trình ... – user128026

+0

đồng ý nhưng sự khác biệt giữa khả năng truy cập –

+0

@dspinozzi: các hàm tạo cho các biến chung được gọi trước main(), nhưng các hàm tạo cho các biến tĩnh được gọi là hàm đầu tiên được gọi là. Cả hai loại biến thường được lưu trữ trong cùng một phần của bộ nhớ - tôi nghĩ GCC đặt chúng trong phần .data. – Neil

Trả lời

123

Kể từ khi tôi đã không hài lòng với câu trả lời, và hy vọng rằng các karjatkar sameer muốn tìm hiểu thêm hơn là chỉ đơn giản có/không trả lời, here you go.

Điển hình là một quá trình có 5 khu vực khác nhau của bộ nhớ phân bổ

  1. Mã - đoạn văn bản
  2. Khởi tạo dữ liệu - phân đoạn dữ liệu
  3. uninitialized dữ liệu - bss phân khúc
  4. Heap
  5. stack

Nếu bạn thực sự muốn tìm hiểu những gì được lưu ở đâu sau đó đọc và đánh dấu trang này:

COMPILER, ASSEMBLER, LINKER AND LOADER: A BRIEF STORY (nhìn vào Bảng w.5)

Anatomy of a Program in Memory

alt text http://www.tenouk.com/ModuleW_files/ccompilerlinker006.png

+0

Điều đó có nghĩa là dữ liệu Uninitialized - bss và dữ liệu khởi tạo là một phần của heap? –

+0

Không, chúng không phải là một phần của đống, chúng ở các khu vực khác nhau như được viết trong câu trả lời của tôi (5 lĩnh vực khác nhau). Heap và stack chiếm bộ nhớ ảo phía trên đoạn văn bản và dữ liệu. – Milan

+6

Điểm quan trọng là phân đoạn bss và dữ liệu được cấp phát khi chương trình được nạp lần đầu tiên vào bộ nhớ và kích thước của chúng không thay đổi khi nó chạy. Các nội dung của heap tương phản là dễ bay hơi và thay đổi trong suốt quá trình chạy, khi các hoạt động bộ nhớ động được thực hiện. – quark

6

Cả. Đó là phần .data.

+0

Nó phụ thuộc nếu bộ nhớ toàn cục được cấp phát trực tiếp hoặc phân bổ động từ ứng dụng –

+1

Nếu bộ nhớ được cấp động không phải là toàn cục (theo nghĩa toàn cầu) – EFraim

+0

có thể gây tranh cãi :) –

5

bộ nhớ toàn cầu là tiền được phân bổ trong một khối bộ nhớ cố định, hoặc trên heap, tùy thuộc vào cách nó được phân bổ bởi ứng dụng của bạn:

byte x[10]; // pre-allocated by the compiler in some fixed memory block 
byte *y 

main() 
{ 
    y = malloc(10); // allocated on the heap 
} 

EDIT:

Câu hỏi đặt ra gây nhầm lẫn: Nếu tôi phân bổ cấu trúc dữ liệu trên toàn cầu trong ứng dụng C++, nó có sử dụng bộ nhớ ngăn xếp hoặc bộ nhớ heap không?

"phân bổ"? Điều đó có thể có nghĩa là nhiều thứ, bao gồm gọi malloc(). Nó sẽ khác nếu câu hỏi là "nếu tôi tuyên bố và khởi tạo một cấu trúc dữ liệu trên toàn cầu".

Nhiều năm trước, khi CPU vẫn đang sử dụng phân đoạn 64K, một số trình biên dịch đủ thông minh để phân bổ bộ nhớ động từ vùng nhớ thay vì đặt một khối trong phân đoạn .data (do giới hạn trong kiến ​​trúc bộ nhớ).

Tôi đoán Tôi chỉ là quá già ....

+0

Đó là ngữ nghĩa. Tôi đoán đó là giá trị một downvote –

+0

Nó sais "phân bổ trên heap" và đó là khá chính xác. Trừ khi câu hỏi này được gắn cờ "người mới" hoặc "người mới bắt đầu" thì đây là lời nhắc đầy đủ về những gì đang xảy ra. –

+0

@Don: Không. Điều toàn cục là con trỏ chứ không phải bộ nhớ mà nó trỏ đến. Bạn có thể xử lý bộ nhớ theo cách bạn muốn. Không có nó để ở lại cho tất cả các hoạt động. Bạn thậm chí có thể chỉ nó vào ngăn xếp đôi khi. – EFraim

-3

Nếu bạn đang phân bổ một cách rõ ràng bộ nhớ chính mình bằng cách mới hoặc malloc, sau đó nó sẽ được phân bổ trong heap. Nếu trình biên dịch phân bổ bộ nhớ, thì nó sẽ được cấp phát trên ngăn xếp.

+0

bộ nhớ toàn cầu không bao giờ được cấp phát trên ngăn xếp. Ngăn xếp chỉ được sử dụng cho biến cục bộ và tham số –

+0

biến ngăn xếp được "hủy" khi hàm trả về – user128026

13

Thông thường nó không tiêu thụ. Nó cố gắng phân bổ chúng trong một phân đoạn bộ nhớ có khả năng duy trì kích thước không đổi cho việc thực hiện chương trình. Nó có thể là bss, stack, heap hoặc data.

+0

Bằng cách chỉnh sửa tệp boot.ini, chúng tôi có thể mở rộng bộ nhớ ảo thành 3GB. Giống như khôn ngoan là có bất kỳ thiết lập cho phân khúc bộ nhớ? –

+0

Điều đó sẽ là vô nghĩa, bởi vì kích thước của bộ nhớ phân bổ tĩnh không bao giờ có thể thay đổi –

-1

biến toàn cầu trực tiếp trên heap. Đây là một trường hợp đặc biệt bởi vì chúng sống trong cuộc đời của chương trình

0

Đối tượng toàn cầu sẽ chiếm bộ nhớ mà thời gian chạy hoặc trình biên dịch dự trữ trước khi chính được thực hiện, đây không phải là chi phí thời gian chạy thay đổi. đống.

Nếu ctor của đối tượng cấp phát bộ nhớ, nó sẽ nằm trong heap và mọi phân bổ tiếp theo của đối tượng sẽ là phân bổ đống.

Nó phụ thuộc vào bản chất chính xác của đối tượng chung, nếu đó là một con trỏ hoặc toàn bộ đối tượng đó là toàn cầu.

26

Vấn đề ở đây là câu hỏi. Giả sử bạn đã có một C nhỏ (++ là tốt, họ xử lý này cùng một cách) chương trình như thế này:

/* my.c */ 

char * str = "Your dog has fleas."; /* 1 */ 
char * buf0 ;       /* 2 */ 

int main(){ 
    char * str2 = "Don't make fun of my dog." ; /* 3 */ 
    static char * str3 = str;   /* 4 */ 
    char * buf1 ;      /* 5 */ 
    buf0 = malloc(BUFSIZ);   /* 6 */ 
    buf1 = malloc(BUFSIZ);   /* 7 */ 

    return 0; 
} 
  1. này được không cấp phát trên stack NOR trên heap. Thay vào đó, nó được phân bổ dưới dạng dữ liệu tĩnh và được đưa vào phân đoạn bộ nhớ riêng của nó trên hầu hết các máy hiện đại. Chuỗi thực tế cũng đang được phân bổ dưới dạng dữ liệu tĩnh và được đưa vào phân khúc chỉ đọc trong các máy suy nghĩ đúng.
  2. đơn giản chỉ là con trỏ được phân bổ tĩnh; phòng cho một địa chỉ, trong dữ liệu tĩnh.
  3. có con trỏ được phân bổ trên ngăn xếp và sẽ được phân phối lại hiệu quả khi trả lại main. Chuỗi, vì nó là một hằng số, được cấp phát trong không gian dữ liệu tĩnh cùng với các chuỗi khác.
  4. thực sự được phân bổ chính xác như ở 2. Từ khóa static cho bạn biết rằng nó không được phân bổ trên ngăn xếp.
  5. ... nhưng buf1 đang ở trên ngăn xếp và
  6. ... không gian bộ đệm malloc'ed nằm trên heap.
  7. Và nhân tiện, trẻ em không thử ở nhà. malloc có giá trị trả lại lãi; bạn nên luôn luôn kiểm tra giá trị trả lại.

Ví dụ:

char * bfr; 
if((bfr = malloc(SIZE)) == NULL){ 
    /* malloc failed OMG */ 
    exit(-1); 
} 
+0

Không gian đệm malloced không có gì để làm với các biến toàn cầu. Chỉ có con trỏ là toàn cầu. Làm ơn đừng nhầm lẫn giữa mọi người. – EFraim

+7

Ồ, đừng ngớ ngẩn. Người hỏi rõ ràng không rõ ràng về những gì xảy ra ở đâu, vì vậy tôi đã viết một câu trả lời được hướng dẫn để cải thiện sự hiểu biết của mình. –

2

Không khai báo một cấu trúc dữ liệu toàn cầu trong C++ tiêu thụ bộ nhớ heap hoặc stack. Trên thực tế, các biến toàn cầu thường được phân bổ trong một phân đoạn dữ liệu có kích thước không thay đổi trong toàn bộ chương trình. Ngăn xếp và heap thường được sử dụng cho các biến được tạo và hủy trong khi thực hiện chương trình.

Program Memory Space

Các vấn đề liên quan