2010-08-26 28 views
6

Vì vậy, từ câu hỏi memmove trước đây của tôi, tôi muốn biết cách tìm hướng tăng trưởng ngăn xếp.hướng tăng trưởng ngăn xếp

void stackDirection(int* i) 
    { 

    int j; 

    if(&j>i) 
     cout<<"Stack is growing up \n"<<endl; 
    else 
     cout<<"Stack is growing down \n"<<endl; 


    } 
    int main() 
    {  
     int i=1; 

     stackDirtection(&i); 

} 
+2

Và mã của bạn không hoạt động hoặc sự cố xảy ra ở đâu? – nothrow

+0

Vấn đề là tôi không thể nói liệu mã này có đúng không – brett

+0

imo một thử nghiệm tốt hơn sẽ được gọi tuần tự _alloca, vì các con trỏ ngăn xếp sẽ nằm trong cùng một khung ngăn xếp và sẽ không chịu bất kỳ tối ưu hóa trình biên dịch nào – Necrolis

Trả lời

13

Ngăn xếp có thể không lớn lên hoặc xuống.

Mỗi khung ngăn xếp có thể được phân bổ tại các điểm ngẫu nhiên bên trong vùng heap.
Điều này thực sự được thực hiện trong một số hệ điều hành để thử và ngăn chặn ngăn xếp đập bởi mã độc hại.

Khái niệm về ngăn xếp phát triển theo heap chỉ là cách dễ dàng để dạy khái niệm ngăn xếp (và tất nhiên triển khai sớm đã hoạt động theo cách này đơn giản (không cần phải làm gì đó khó hơn bạn cần khi không ai cố gắng phá vỡ bạn)).

+0

@Martin Stack được tạo trên heap? Tôi nhận được nó? Hệ điều hành tách riêng ngăn xếp từ đống phải và chia chúng thành các trang phải không? Làm thế nào điều này có thể phụ thuộc vào kiến ​​trúc? Bởi vì những gì tôi đang đề cập ở đây là đúng địa chỉ logic và các địa chỉ logic này chỉ là trình biên dịch phụ thuộc đúng không? – brett

+0

@Brett: từ quan điểm của phần cứng, tất cả bộ nhớ chỉ là bộ nhớ. Các hệ điều hành sau đó có thể chọn để làm bất cứ điều gì nó muốn. – Potatoswatter

+1

@brett: Trong những ngày và đống cũ là những thực thể riêng biệt và phát triển theo khái niệm hướng về nhau. Nhưng điều này khá dễ bị hỏng và gây ra việc thực thi mã độc hại. Vì vậy, một số người thông minh có một chút suy nghĩ. Bây giờ một ngăn xếp chỉ là một loạt các khung hình (một cho mỗi cuộc gọi hàm). Không có lý do kỹ thuật họ cần phải đi một cái khác (như hiện tại có một liên kết quay lại cuối cùng). Vì vậy, tại sao không chỉ phân bổ khung stack trong heap bằng cách sử dụng thói quen quản lý bộ nhớ thông thường. Khái niệm: Unwinding ngăn xếp được giải phóng khung hiện tại và sau chuỗi trở lại. –

0

Chức năng của bạn phụ thuộc vào tham số int * có thể trỏ tới bất kỳ đâu và cũng là NULL. Tốt hơn là so sánh địa chỉ của hai biến cục bộ.

+0

Trình biên dịch được tự do phân bổ các biến cục bộ theo bất kỳ thứ tự nào. Có, nó sẽ xây dựng và tiêu diệt chúng theo đúng thứ tự, nhưng nó có thể phân bổ không gian cho chúng bất cứ nơi nào nó muốn. – sharptooth

1

Thử nghiệm như vậy không đáng tin cậy vì bạn có thể gặp phải các ngoại lệ. Trình tối ưu hóa có thể làm hỏng bạn hoặc hệ thống có thể sử dụng thanh ghi cho các tham số. Nếu bạn thực sự phải biết hướng ngăn xếp, hãy đọc hướng dẫn cho bộ xử lý của bạn.

Mặc dù vậy, trừ khi bạn đang viết hệ điều hành hoặc thứ gì đó thực sự cấp thấp, nếu bạn cần biết hướng ngăn xếp, bạn có thể làm điều gì đó xấu xí và khủng khiếp và nên xem xét lại các phương pháp của mình.

0

Điều này nằm ngoài phạm vi của tiêu chuẩn C++. Đó là hành vi được xác định thực hiện và có thể phụ thuộc vào kiến ​​trúc hệ điều hành/bộ vi xử lý cụ thể, v.v.

Tốt nhất là không dựa vào chi tiết như vậy, trừ khi bạn đang xâm nhập vào ETHICAL :) và/hoặc không quan tâm nhiều đến tính di động

0

Xem xét viết lại như sau, trong đó cho thấy một cách thức mà một trình biên dịch có thể thực hiện mã của bạn:

trống stackDirection (int * i) { struct __vars_stackDirection { int j; } * __ stackframe_stackDirection = malloc (sizeof (int));

if(&(__stackframe.j) > i) 
    cout<<"Stack is growing up \n"<<endl; 
else 
    cout<<"Stack is growing down \n"<<endl; 

} int main() {
struct __vars_main { int i; } * __ stackframe_main = malloc (sizeof (int));

stackDirection(&(__stackframe.i)); 

}

Bạn sẽ phải đồng ý rằng __stackframe_stackDirection__stackframe_main sẽ cơ bản ngẫu nhiên. Ngăn xếp có thể lớn lên hoặc xuống.

Tệ hơn nữa, bạn đang giả sử một mô hình lineair. Hoặc là a<b, b<a, or a==b. Nhưng đối với con trỏ này không giữ. Cả ba so sánh a<b, b<a and a==b có thể sai cùng một lúc.

Các vấn đề liên quan