Vùng nhớ Stack trong C?

vậy thời gian sống của biến s có bằng thời gian sống của hàm foo không hay bằng với thời gian sống của chương trình chính vậy @ltd ?

1 Like

ví dụ bạn tạo 1 biến static trong hàm như sau:

void func()
{
    static int i;
}

Thì i là biến static chưa khỏi tạo do đó nó nằm ở BSS giống như anh @ltd nói ở trên, do đó nó chỉ được hủy khi kết thúc chương trình, life time của nó gần như bằng với thời điểm bắt đầu và kết thúc cùng với chương trình của bạn

3 Likes

s sống cho tới khi bị delete[] hoặc cho tới khi tắt chương trình. Lúc đó, hệ điều hành sẽ dọn dẹp vùng nhớ chưa hủy.

2 Likes

các bạn cho mình hỏi tiếp là: sau khi ra khỏi hàm thì chương trình xóa đi biến trong static mem, vậy rất dễ bị lỗi dangling reference đúng không?
trong đoạn code của mình ở trên biến r có thể xảy ra dangling referece không vậy?

1 Like

Biến static sẽ không bị xóa khi ra khỏi hàm.

1 Like

sẽ test nhiều với class và struct. em dùng con trỏ còn hơi rối. mất thêm 10ph nếu dùng. mà dùng biến bình thường thì tham chiếu nó ko mạnh bằng con trỏ. :smile:

1 Like

Topic này đâu nói tới struct hay class đâu em? Cả Con trỏ và tham chiếu nữa? hay em post nhầm topic :expressionless:

1 Like

ko nhầm theo ý em có lẽ sai với topic thôi anh. :wink:

1 Like

Thấy các bạn tranh luận nhiều nên mình có thể giới thiệu các bạn cách nhận biết đơn giản về stack và heap thế này.

  1. Các biến khai báo dạng mảng (array) với kích thước cố định : là stack
    ví dụ: int a[100];

  2. Các dữ liệu khai báo dưới dạng được cấp phát bộ nhớ qua các từ khoá như : alloc() , malloc() trong C, hay new trong C++ : là heap

  3. Sau khi thoát khỏi chương trình, thì stack sẽ được giải phóng để lấy chỗ cho ứng dụng khác khởi tạo. Còn heap thì không, vì vậy khi cấp phát động cần phải giái phóng, cấp bao nhiêu, giải phóng bấy nhiêu để tránh bị memory leak. Các hệ điều hành hiện nay đang có bộ thu dọn bộ nhớ thừa để tránh memory leak, nhưng ko có nghĩa là khi code không phải giải phóng.

Ngoài ra, các bạn trong quá trình code, code nhiều sẽ vỡ ra được thêm. Chứ mới tìm hiểu mà bàn luận để hiểu thì không có ý nghĩa nhiều lắm :smile:

4 Likes

theo mình thấy thì vùng nhớ của biến toàn cục và biến static bản chất giồng nhau nên có thể gộp chung có đúng không?

Khá giống nhau về cách lưu trữ dữ liệu. Nhưng khác nhau nhiều về cách sử dụng. Theo ý @small_hulk mình gộp như thế nào?

1 Like

thoe mình thì 2 loại biến này mình có thể đưa nó vô chung vùng nhớ stack! vì chúng sau khi chương trình chạy xong chúng mới được giải phóng! biến toàn cục hay static đều thế!

nhờ các bạn giúp mình đưa ra công dụng và ví dụ cho mỗi kiểu sau:

Static
static int x[10];
Fixed Stack-dynamic
int x[10]; //inside a function
Stack-dynamic
cin »n;
int x[n];
Fixed Heap-dynamic
int[] x = new int[10];
Heap-dynamic
cin »n;
int[] x = new int[n];

Bạn hiểu nhầm rồi, biến trong stack sẽ bị hủy ngay lập tức khi ra khỏi hàm chứ không phải khi thoát chương trình. Stack tạo và hủy liên tục khi chương trình đang chạy.

Câu hỏi này chung chung quá. Không thể giải thích được. Thêm nữa, nội dung của topic này không liên quan đến câu hỏi mà bạn đang hỏi.

1 Like

A Đạt nói chí phải. còn mình thì chưa tìm hiểu sâu về vùng nhớ nắm. chỉ có xoá sau khi tạo. dân quèn nên nhiều lúc mình mặc nó. ram cũng ko tôn lắm. sau này nếu code nhiều có lẽ sẽ tự nước chảy thành sông giống anh Lập trình sư đã nói

Anh Đạt cho em hỏi, như trong code của bạn ở trên, thì s nằm trong stack, nếu trong stack thì ra khỏi hàm thì sẽ bị xóa, em nghĩ vùng nhớ sẽ sống đến hết chương trình là vùng nhớ mà s trỏ tới, chứ không phải là s. Không biết như vậy có đúng không

Hi @thuan, Topic này đã 10 tháng trước rồi nên Đat không biết chính xác là bạn đang nói về đoạn code nào. @thuan cho biết cụ thể đoạn code được không?

Đoạn code này đó anh :slight_smile:

int p[10];
int foo(int x) {
    static int q [10] ;
    int r [10] ;
    int s = new int [10] ;
    switch ( x ) {
    case 1 :
        return p ;
    case 2 :
        return q ;
    case 3 :
        return r ;
    case 4 :
        return s ;
    default :
        foo ( x+1);
    }
}
int p[10];
int foo(int x) {
    static int q [10] ;
    int r [10] ;
    int s = new int [10] ;
    switch ( x ) {
    case 1 :
        return p ;
    case 2 :
        return q ;
    case 3 :
        return r ;
    case 4 :
        return s ;
    default :
        foo ( x+1);
    }
}

Đúng vậy.

Thấy mọi người trả lời sôi nổi và đầy đủ rồi nhưng đối với những bạn newbie thì sẽ hơi rắc rối nên mình nêu ý kiến đơn giản của mình cho các bạn mới học lập trình dễ hiểu luôn nhé (các pro đừng chém mình)
Trong bộ nhớ được chia làm 4 phần chính:

  • Code Segment
  • Data Segment
  • Heap
  • Stack

=> Code segment là nơi lưu trữ mã máy dạng nhị phân. Tức là chương trình bạn code thì bạn code bằng ngôn ngữ tự nhiên của con người (như if, else, for, int, …) nhưng cần phải dịch sang dạng nhị phân (1010111010001 …) thì máy tính mới hiểu được code.

=> Data Segment là nơi chứa các biến tĩnh (như static) và biến toàn cục. (biến nằm ngoài các hàm)

=> Heap là vùng nhớ không do CPU quản lý, lập trình viên sẽ quản lý vùng nhớ này. Tức là vùng nhớ này sẽ quản lý các con trỏ mà bạn cấp phát bộ nhớ. Nói cách khác, vùng nhớ Heap dành cho con trỏ.

=> Stack là vùng nhớ do CPU quản lý, lập trình viên không thể can thiệp vào, nếu cố tình can thiệp sẽ bị lỗi. Vùng nhớ này chứa các biến cục bộ (biến được bao phủ bởi dấu {} ).

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?