Biến của bạn d
thường không xuất hiện trong ngăn xếp. Niềng răng xoăn không biểu thị một khung ngăn xếp. Nếu không, bạn sẽ không thể làm một cái gì đó như thế này:
char var = getch();
{
char next_var = var + 1;
use_variable(next_char);
}
Nếu các dấu ngoặc nhọn gây ra một lần đẩy / bật ngăn xếp thực sự (giống như một lệnh gọi hàm), thì đoạn mã trên sẽ không biên dịch được vì mã bên trong dấu ngoặc nhọn sẽ không thể truy cập vào biến var
nằm ngoài dấu ngoặc (giống như một hàm con chức năng không thể truy cập trực tiếp các biến trong chức năng gọi). Chúng tôi biết rằng đây không phải là trường hợp.
Niềng răng xoăn đơn giản được sử dụng cho phạm vi. Trình biên dịch sẽ coi mọi quyền truy cập vào biến "bên trong" từ bên ngoài dấu ngoặc nhọn là không hợp lệ và nó có thể sử dụng lại bộ nhớ đó cho mục đích khác (điều này phụ thuộc vào việc triển khai). Tuy nhiên, nó có thể không được bật ra khỏi ngăn xếp cho đến khi hàm kèm theo trở lại.
Cập nhật: Đây là những gì thông số kỹ thuật C đã nói. Về các đối tượng có thời gian lưu trữ tự động (mục 6.4.2):
Đối với một đối tượng không có kiểu mảng có chiều dài thay đổi, thời gian tồn tại của nó kéo dài từ mục nhập vào khối mà nó được liên kết cho đến khi việc thực hiện khối đó kết thúc bằng mọi cách.
Phần tương tự định nghĩa thuật ngữ "trọn đời" là (nhấn mạnh của tôi):
Thời gian tồn tại của một đối tượng là một phần của việc thực hiện chương trình trong đó lưu trữ được đảm bảo được dành riêng cho nó. Một đối tượng tồn tại, có một địa chỉ không đổi và giữ lại giá trị được lưu trữ cuối cùng trong suốt vòng đời của nó. Nếu một đối tượng được đề cập đến bên ngoài vòng đời của nó, hành vi không được xác định.
Từ khóa ở đây, tất nhiên, là 'được bảo đảm'. Khi bạn rời khỏi phạm vi của bộ dấu ngoặc trong, thời gian tồn tại của mảng sẽ kết thúc. Bộ nhớ có thể vẫn có thể được phân bổ cho nó (trình biên dịch của bạn có thể sử dụng lại không gian cho thứ khác), nhưng mọi nỗ lực truy cập vào mảng đều gọi hành vi không xác định và mang lại kết quả không thể đoán trước.
Thông số C không có khái niệm về khung stack. Nó chỉ nói về cách chương trình kết quả sẽ hoạt động và để lại các chi tiết thực hiện cho trình biên dịch (xét cho cùng, việc triển khai sẽ trông khá khác biệt trên CPU không có ngăn xếp so với CPU có ngăn xếp phần cứng). Không có gì trong thông số C bắt buộc trong đó khung stack sẽ hoặc không kết thúc. Cách thực sự duy nhất để biết là biên dịch mã trên trình biên dịch / nền tảng cụ thể của bạn và kiểm tra tập hợp kết quả. Bộ tùy chọn tối ưu hóa hiện tại của nhà biên dịch của bạn cũng có thể đóng vai trò trong việc này.
Nếu bạn muốn đảm bảo rằng mảng d
không còn chiếm bộ nhớ trong khi mã của bạn đang chạy, bạn có thể chuyển đổi mã trong dấu ngoặc nhọn thành một chức năng riêng biệt hoặc rõ ràng malloc
và free
bộ nhớ thay vì sử dụng lưu trữ tự động.