Thủ Thuật về Mảng được lưu ở đâu Chi Tiết
Bạn đang tìm kiếm từ khóa Mảng được lưu ở đâu được Update vào lúc : 2022-04-06 05:53:08 . Với phương châm chia sẻ Thủ Thuật Hướng dẫn trong nội dung bài viết một cách Chi Tiết 2022. Nếu sau khi tìm hiểu thêm nội dung bài viết vẫn ko hiểu thì hoàn toàn có thể lại Comment ở cuối bài để Ad lý giải và hướng dẫn lại nha.Hiểu được sơ đồ, kiến trúc những vùng nhớ của một chương trình sẽ hỗ trợ bạn viết code một những hiệu suất cao và tối ưu. Mỗi vùng nhớ trong một chương trình lại sở hữu tính chất rất khác nhau. Về cơ bản trong một chương trình C, bộ nhớ được biểu lộ bởi những vùng sau:
- Vùng Text
- Vùng tài liệu đã được khởi tạo
- Vùng tài liệu không được khởi tạo
- Vùng Stack
- Vùng Heap
Chương trình cơ sở
Xét đoạn code sau:
#includeChương trình không chứa bất kỳ một biến nào, nên ta sẽ sử dụng nó để so sánh sự thay đổi kích thước trong vùng nhớ bằng lệnh size(1). Lệnh size(1) cho ta biết kích thước (byte) của những vùng text, DS, BSS.
Kiểm tra kích thước những vùng nhớ bằng phương pháp lưu đoạn code trên vào 1 file source code "test.c" và làm như sau:
$ gcc test.c -o memory-layout-no-var
$ size memory-layout-no-var
text data bss dec hex filename
1115 552 8 1675 68b memory-layout-no-var
Chú ý: Trong phạm vi nội dung bài viết này chúng tôi chỉ hướng dẫn cách kiểm tra kích thước những vùng nhớ trên hệ điều hành quản lý Linux (ubuntu, centos ...). Nếu những bạn đang dùng windown hoàn toàn có thể dùng linux trực tuyến terminal[1]
Vùng Text
Các tên khác: text segment hay code segment.
Vùng này chứa mã máy của chương trình đã được biên dịch.
Vùng text segment của một đối tượng người dùng file hoàn toàn có thể thực thi được thường là vùng nhớ chỉ đọc, điều này là để tránh việc chương trình vô tình bị sửa đổi không như mong ước.
Thông thường vùng này là vùng nhớ chia sẻ nên ta chỉ việc một phiên bản sao chép tồn tại trong bộ nhớ cho những chương trình thực thi thường xuyên.
Vùng tài liệu đã được khởi tạo
Các tên khác: Initialized data segment, data segment (DS)
Để cho ngắn gon ta sẽ sử dụng "DS" như tên của vùng này.
DS là một phần trong bộ nhớ ảo của chương trình, nơi chứa những biến toàn cục, biến tĩnh hoặc các biến hằng đã được khởi tạo trong code.
Trong ví dụ sau các biến a và b sẽ được chứa trong vùng nhớ này.
#includeChú ý rằng DS không phải là vùng nhớ chỉ đọc, bởi vì giá trị của các biến có thể được thay đổi khi chạy runtime.
Thực ra vùng nhớ này có thể chia ra làm hai vùng nhỏ hơn, vùng khởi tạo chỉ đọc dùng để chứa các biến hằng, và vùng khởi tạo đọc-ghi để chứa các biến toàn cục và biến tĩnh thông thường.
Ta lưu đoạn code trên vào file "ds.c", thực thi biên dịch bằng gcc và kiểm tra kích thước của chương trình trong những vùng nhớ bằng lệnh size để thấy được sự thay đổi giá trị của những vùng nhớ so với chương trình cơ sở ở trên.
$ gcc ds.c -o memory-layout-ds
$ size memory-layout-ds
text data bss dec hex filename
1250 568 8 1826 722 memory-layout-ds
Nhận thấy chỉ có kích thước của vùng text (do lượng code logic tăng thêm) và data thay đổi so với chương trình cơ sở. điều này chứng tỏ những biến a, b, c ở trên đã được lưu vào vùng tài liệu đã được khởi tạo.
Vùng dữ liệu chưa được khởi tạo
Các tên khác: Uninitialized Data Segment hay vùng BSS
Dữ liệu trong vùng này được khởi tạo bởi nhân của hệ điều hành quản lý về giá trị 0 trước lúc chương trình được thực sự thực thi.
Vùng này chứa những biến toàn cục và những biến tĩnh được khởi tạo với những giá trị 0 (zero) hoặc không được khởi tạo với bất kỳ giá trị nào trong source code.
Trong ví dụ sau các biến global và i sẽ được chứa trong vùng nhớ bss.
#includeLưu chương trình vào file bss.c và thực thi như sau để kiểm tra sự thay đổi kích thước cách vùng nhớ so với chương trình cơ sở.
$ gcc bss.c -o memory-layout-bss
$ size memory-layout-bss
text data bss dec hex filename
1115 552 16 1683 693 memory-layout-bss
Trong trường hợp này chỉ có vùng bss thay đổi kích thước so với chương trình cơ sở, vậy nên kết luận những biến không được khởi tạo "global" và "i" được lưu trong vùng bss là đúng chuẩn.
Vùng nhớ Stack
Vùng nhớ stack thường nằm sát kề với vùng heap. Hai vùng nhớ này tăng trưởng theo chiều đối nhau. Ví trí đỉnh của stack được ghi lại bằng stack pointer, vị trí đỉnh của heap được đánh đấu bằng heap pointer. Khi hai con trỏ này gặp nhau cũng là lúc bộ nhớ dành riêng cho chúng bị hết sạch.
Tuy nhiên bạn không cần quá lo ngại về yếu tố ở trên vì ngày này phần cứng của cục nhớ (RAM vật lý) đã được tăng thêm, hơn thế nữa người ta cũng vận dụng những kỹ thuật đánh địa chỉ ảo (bộ nhớ ảo), làm cho hai vùng này to nhiều hơn thật nhiều.
Vùng nhớ stack tuân theo cấu trúc LIFO (Last In First Out)và có một thanh ghi stack pointer để lưu giữ vị trí đỉnh của nó.
Các loại tài liệu được chứa trong vùng nhớ này gồm có:
- Biến cục bộ, biến tạm.
- Địa chỉ trả về sau mỗi lời gọi hàm.
- Các tham số truyền vào những hàm.
Các thuật toán đệ quy được thực thi nhờ vào hoạt động và sinh hoạt giải trí của stack và chúng được vận dụng thật nhiều trong thực tiễn.
Lỗi hoàn toàn có thể gặp với vùng nhớ này đó đó là "stack overflow" khi mà ta sử dụng đệ quy không kết quả cuối cùng hoặc đệ quy quá sâu. Nó cũng hoàn toàn có thể xẩy ra khi ta cấp. phát một lượng bộ nhớ quá rộng, vượt quá số lượng giới hạn của stack.
Các biến tạo trong vùng nhớ này hoàn toàn có thể tự động hóa được tịch thu, nên ta không còn nhu yếu các kỹ thuật tịch thu bộ nhớ như khi ta cấp phép động trong heap.
Vùng nhớ Heap
Ngoài những đặc tính đã được đề cập ở trên vùng nhớ heap còn tồn tại một số trong những đặc tính sau:
Các biến chứa trong vùng nhớ này phải được tịch thu thủ công minh phương pháp sử dụng những hàm delete, delete [] và không lấy phí trong C/C++.
Việc cấp phép bộ nhớ cho một biến trong vùng này là châm hơn so với việc cấp phép trong stack. Có thể lý giải nguyên do này là vì vùng nhớ trong stack là luôn luôn liên tục nên việc cấp phép thuận tiện và không cầu kỳ.
Lỗi phân mảnh bộ nhớ hay xẩy ra với bộ nhớ này qua thời hạn sử dụng lâu, vì ta đã thực thi nhiều thao tác cấp phép và tịch thu bộ nhớ trong nó, để lại nhiều vùng nhớ trống vô cùng nhỏ, khó xử dụng được.
Trong C/C++ hoàn toàn có thể cấp phép trong vùng nhớ này qua những hàm new, malloc, calloc … Việc cấp phép hoàn toàn có thể không thành công xuất sắc do lượng cấp phép vượt quá số lượng giới hạn của heap.
Vùng nhớ này thường được chỉa sẻ bởi những thư viện chia sẻ (shared libraries) hoặc những mô đun được tải động trong những tiến trình.
Hiểu về phương pháp hoạt động và sinh hoạt giải trí, tính chất của những vùng nhớ là vô cùng quan trong với những lập trình viên viết những ngôn từ bậc thấp như C/C++, Assembly.
Tuy nhiên nó cũng luôn có thể có ích với bất kể lập trình viên nào để giúp họ cải tổ được vận tốc, khả năng của chương trình, giúp tiết kiệm chi phí tài nguyên phần cứng và chương trình chạy hiệu suất cao hơn. Bạn hoàn toàn có thể tìm hiểu thêm về những cấu trúc tài liệu stack và heap để hiểu sâu hơn về kiểu cách hoạt động và sinh hoạt giải trí của hai vùng nhớ quan trọng này.