Cấp phát và giải phóng bộ nhớ trong lập trình C – Minh Hoàng Blog | Cùng nhau chia sẻ kiến thức lập trình, tự học tiếng Nhật online và cuộc sống Nhật Bản!

1. Tổ chức bộ nhớ trong máy tính như thế nào?

1.

Tổ chức bộ nhớ trong máy tính như thế nào?

Trước khi tìm hiểu về cấp phát và giải phóng bộ nhớ, chúng ta cần biết được là bộ nhớ máy tính được tổ chức thế nào. Dưới đây là hình ảnh minh họa cho thứ tự các phân vùng trên bộ nhớ ảo:

1.1.

Code Segment

Code segment (text segment): Là nơi lưu trữ mã máy dạng nhị phân. Có nghĩa là các chương trình mà chúng ta code là code trên ngôn ngữ tự nhiên, nhưng khi ở phân vùng này nó sẽ ở dạng mã máy nhị phân. Code segment chỉ chịu sự chi phối của hệ điều hành, người lập trình không thể can thiệp trực tiếp đến phân vùng này.

1.2.

Data Segment

Data segment (initialized data segment): Là nơi chứa các biến kiểu static, biến toàn cục (global variable).

1.3.

BSS Segment

BSS segment (uninitialized data segment) cũng được dùng để lưu trữ các biến kiểu static, biến toàn cục (global variable) nhưng chưa được khởi tạo giá trị cụ thể.

1.4.

Heap

Là vùng nhớ không do CPU quản lý, người lập trình phải tự quản lý vùng nhớ này. Nó được sử dụng khi thực hiện cấp phát bộ nhớ động dùng cho con trỏ.

1.5.

Stack

Call Stack (thường được gọi là Stack): Là vùng nhớ do CPU quản lý, người lập trình không thể can thiệp vào vùng nhớ này. Nếu cố tình can thiệp sẽ bị lỗi (code bên dưới, bạn chạy thử xem nó hiện thông báo lỗi như thế nào nhé). Vùng nhớ Stack được dùng để cấp phát bộ nhớ cho tham số của các hàm (function parameters) và biến cục bộ (local variables).

#include <stdio.h>

int main()
{
	int a = 5;		// Khai báo 1 biến bình thường a => a thuộc vùng nhớ STACK

	int *p;			// Khai báo biến con trỏ p => p thuộc vùng nhớ HEAP
	
	p = &a;			// Cho p trỏ tới biến a => p lúc này cũng thuộc vùng nhớ STACK

	free(p);		// Vì vậy, nếu chúng ta thực hiện giải phóng vùng nhớ của p
					// thì sẽ bị lỗi do đang giải phóng vùng nhớ STACK
	return 0;
}