Sự khác nhau giữa bộ nhớ stack và heap?

Bộ nhớ stack và heap đều được lưu trên RAM của PC.  Dưới đây là một số điểm khác nhau của stack và heap.

Stack Heap
  • Vùng nhớ được cấp phát khi chương trình được biên dịch.
  • Vùng nhớ được cấp phát khi chạy chương trình (run-time).
  • Vùng nhớ stack được sử dụng cho việc thực thi thread. Khi gọi hàm, các biến cục bộ của hàm được lưu trữ vào block của stack (theo kiểu LIFO). Cho đến khi hàm trả về giá trị, block này sẽ được xóa tự động. Hay nói cách khác, các biến cục bộ được lưu trữ ở vùng nhớ stack và tự động được giải phóng khi kết thúc hàm.
  • Vùng nhớ heap được dùng cho cấp phát bộ nhớ động (malloc( ), new( )). Vùng nhớ được cấp phát tồn tại đến khi lập trình viên giải phóng vùng nhớ bằng lệnh free( ) hoặc delete.
  • Kích thước vùng nhớ stack được fix cố định. Chúng ta không thể tăng hoặc giảm kích thước vùng nhớ stack. Nếu không đủ vùng nhớ stack, gây ra stack overflow. Hiện tượng này xảy ra khi nhiều hàm lồng nhau hoặc đệ quy nhiều lần dẫn đến không đủ vùng nhớ.
  • Khi kích thước vùng nhớ heap không đủ cho yêu cầu malloc( ), new. Hệ điều hành sẽ có cơ chế tăng kích thước vùng nhớ heap.

Ví dụ: Minh họa stack được sử dụng khi gọi hàm

#include <stdio.h>
#include <conio.h>

int MAX(int, int);

void main( void )
{
    int a = 5, b = 7;
    int max = MAX(a, b);
    printf("\nMAX(%d, %d) = %d", a, b, max);
    getch();
}

int MAX(int a, int b)
{
    return (a > b ? a : b);
}

Giải thích:

Trên đây là chương trình tìm giá trị lớn nhất của 2 số nguyên. Khi chạy chương trình ở chế độ debug và xem call stack trên visual studio.

Call Stack
Call Stack

Các bạn nhìn Call Stack sẽ thấy hàm main( ) gọi hàm MAX( ). Hàm main( ) và MAX( ) được lưu theo quy tắc (LIFO: last in – first out). Khi kết thúc hàm MAX( ), các thông tin lưu trữ hàm MAX( ) bị xóa, stack chỉ lưu trữ thông tin của hàm main( ). Tương tự như vậy, khi kết thúc hàm main( ), stack được xóa hoàn toàn.

Call stack
Call stack

4 Comments on Sự khác nhau giữa bộ nhớ stack và heap?

  1. Automatic memory allocation cũng dùng Stack partition nhé bạn, nên không thể nói là “Vùng nhớ được cấp phát khi chương trình được biên dịch”.

    • @cuong,
      Ở đây mình chỉ muốn nhấn mạnh 2 khái niệm memory (stack và heap), nó được dùng để làm gì, lưu trữ cái gì?
      Mình chưa nghe khái niệm “Automatic memory allocation” mà bạn đề cập đến. Bạn nói giúp mình “Automatic memory allocation” được dùng để lưu trữ kiểu dữ liệu nào dc ko?
      Thank bạn đã chia sẻ

      • @VietVH
        Theo mình tìm hiểu thì:
        https://en.wikipedia.org/wiki/Automatic_variable
        Automatic memory allocation là quá trình cấp phát automatic variable (thuộc local variable). Các biến này được cấp phát tự động khi chương trình đi vào bên trong variable’s scope và được xóa khi đi ra, các biến này được cấp trên stack, nên những thứ nằm trên stack có thể được cấp phát trong quá trình chạy chứ không phải là vùng được cấp khi biên dịch. Nên có vẻ nói stack được cấp phát khi chương trình được biên dịch là không đúng.
        Cám ơn bạn vì bài viết hay và bổ ích.

Leave a Reply