Stack và Heap là gì? Phần 1: Stack

Stack và Heap là hai vùng nhớ cơ bản trong một chương trình máy tính. Khi lập trình, chúng ta thường làm việc với chúng mà không hề hay biết. Hiểu được ưu nhược của từng vùng nhớ sẽ giúp ta kiểm soát chương trình hiệu quả hơn.

Khi máy tính chạy một chương trình, chương trình đó sẽ được giao cho một vùng nhỏ trên RAM, ta gọi đó là vùng nhớ. Mỗi chương trình đều có 2 vùng nhớ mà ta cần quan tâm hơn cả đó là Stack và Heap.

Stack

Bạn có thể tưởng tượng Stack như một chồng đĩa. Khi ta muốn lấy một chiếc đĩa, ta chỉ cần lấy chiếc ở trên cùng và khi bắt đầu xếp chồng đĩa ấy, ta sẽ bắt đầu từ dưới lên.

Ta gọi thứ tự xếp đĩa này là LIFO: Last In - First Out. Chiếc đĩa nào được đặt vào cuối cùng sẽ được lấy ra đầu tiên. Ngược lại, chiếc đĩa được đặt vào đầu tiên sẽ được lấy ra cuối cùng


Ta gọi LIFO là một kiểu cấu trúc dữ liệu. Những dữ liệu của ta ở vùng nhớ Stack cũng được quản lý một cách tương tự. Bây giờ có thể bạn vẫn chưa hình dung được và để mình có thể nói sâu hơn về cách hoạt động của Stack, ta cần biết làm cách nào để tạo dữ liệu trên bộ nhớ Stack đã.

Một điều bất ngờ cho bạn đây, bất cứ khi nào bạn khai báo một biến đơn giản như vầy:
tức là bạn đã tạo một phần tử trong vùng nhớ Stack rồi đấy. Đúng vậy, tất cả những khai báo biến thông thường đều được quản lý trên Stack.

Ta có thể hình dung như sau
Khi khai báo biến, ta ghi giá trị của biến vào một chiếc đĩa, rồi đặt chiếc đĩa đó vào chồng đĩa. Nếu sau đó, ta khai báo thêm một biến b, thì chiếc đĩa chứa giá trị của b sẽ được đặt ở trên a.

Tại sao lại phải sử dụng chồng đĩa?

Sử dụng cách quản lý này giúp máy tính nhận biết khi nào cần giải phóng bộ nhớ dễ dàng hơn. Ví dụ, nếu 2 biến a và b vừa rồi được khai báo trong hàm main, khi hàm main kết thúc thì máy tính chỉ cần vứt chồng đĩa của hàm main, và thế là mọi biến được sử dụng trong hàm main đã được giải phóng.

Đó cũng là nguyên nhân dẫn đến khái niệm variable scope. Sau khi một hàm kết thúc thì những biến trong Stack của hàm đó đã bị giải phóng bởi máy tính rồi nên ta không thể truy cập được nữa.

Các đặc điểm của Stack

  • Dễ dàng truy xuất dữ liệu
  • Tự động giải phóng bộ nhớ
  • Vùng nhớ được cấp cho Stack khá ít
  • Có một giới hạn về kích thước của các phần tử có thể chứa trên Stack
  • Phân bố tĩnh: các biến đã được biết trước về kích thước ở thời điểm biên dịch. Đó cũng là lý do độ dài của mảng phải là hằng số nếu ta khai báo theo cách thông thường

Tạm kết

Stack được biết tới do sự tiện lợi của nó. Ta không cần phải lo đến việc giải phóng bộ nhớ đã sử dụng nhưng những giới hạn của nó về kích thước dẫn đến sự tồn tại của vùng nhớ Heap mà ta sẽ tìm hiểu ở phần sau.

Nhận xét

Bài đăng phổ biến từ blog này

Phép phân tích ma trận A=LU

Thuật toán tính lũy thừa nhanh. Giải thích một cách đơn giản

Độc lập tuyến tính và phụ thuộc tuyến tính