2010-08-26 20 views
6

Önceki memmove sorusundan, yığın büyümesinin yönünü nasıl bulacağımı bilmek istiyorum.yığın büyüme yönü

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

Ve kodunuz çalışmıyor ya da sorun nerede? – nothrow

+0

Sorun şu ki bu kodun doğru olup olmadığını söyleyemiyorum – brett

+0

imo daha iyi bir test sıralı _alloca çağrıları olacaktır, yığın işaretçileri aynı yığın çerçevesinde olacak ve herhangi bir derleyici optimizasyonuna tabi olmayacaktır – Necrolis

cevap

13

Yığın yukarı veya aşağı büyüyebilir.

Her bir yığın çerçevesi, yığının içinde rastgele noktalara tahsis edilebilir.
Bu, aslında kötü amaçlı kod tarafından yığın parçalamayı denemek ve önlemek için birkaç OS'de yapılır.

Yığına doğru büyüyen bir yığın kavramı, bir yığın kavramını öğretmenin kolay bir yoludur (ve elbette, erken uygulamalar, bu şekilde işe yaramazdı (ihtiyaç duyduğunuzdan daha zor bir şey yapmaya gerek yoktur) kimse seni kırmaya çalışmıyor)).

+0

@Martin Stack, yığında oluşturuldu mu? Ben anlayamıyorum? İşletim sistemi yığından yığın yığınını ayırır ve bunları sayfalara ayırır? Bu nasıl mimariye bağlı olabilir? Çünkü burada atıfta bulunduğum şey mantıklı adreslerdir ve bu mantıksal adresler sadece derleyiciye bağımlıdır? – brett

+0

@Brett: Donanımın perspektifinden, tüm hafıza sadece hafızadır. OS daha sonra istediğini yapmaya karar verebilir. – Potatoswatter

+1

@brett: Eski günlerde yığın ve yığınlar ayrı ayrı varlıklardı ve kavramsal olarak birbirlerine doğru büyüdü. Ancak bu bozuk ve kötü amaçlı kod yürütmesine neden olmak oldukça kolaydı. Yani bazı zeki insanlar biraz düşünmüştü. Artık bir yığın sadece bir dizi çerçevedir (her işlev çağrısı için bir tane). Birbiri ardına gitmek için ihtiyaç duydukları teknik bir neden yoktur (mevcut olanın sonuncuya kadar bir bağı olduğu gibi). Öyleyse, neden normal bellek yönetimi rutinlerini kullanarak yığın yığınlarını yığına ayırmıyoruz. Kavramsal olarak: Yığının serbest bırakılması mevcut çerçeveyi serbest bırakıp zinciri geri takip eder. –

0

İşleviniz, herhangi bir yere işaret edebilen int * parametresine ve ayrıca NULL olana bağlıdır. İki yerel değişkenin adreslerini karşılaştırmak daha iyidir. Eğer istisnalarıyla çalışabilir, çünkü bu gibi

+0

Derleyici, yerel değişkenleri herhangi bir sıraya ayırmak için ücretsizdir. Evet, onları doğru sırayla inşa edecek ve imha edecek, ancak istediği her yerde onlar için yer ayırabilecektir. – sharptooth

1

Deneyler, güvenilmez. İyileştirici sizi rahatsız edebilir veya sistem parametreler için register kullanabilir. Eğer gerçekten yığın yönünü bilmeniz gerekiyorsa, işlemcinizin kılavuzunu okuyun. ifadesine rağmen

, size muhtemelen bir şey çirkin ve korkunç yapıyoruz yığın yönünü bilmek gerekir ve gerçekten yöntemlerini yeniden gözden geçirilmesi gerektiğini eğer gerçekten bir işletim sistemi ya da bir şey düşük seviyeli yazmadığınız sürece.

0

Bu, C++ standardının kapsamı dışındadır. Uygulama tanımlı bir davranışıdır ve büyük olasılıkla belirli bir OS/işlemci mimarisine bağlıdır.

ETHICAL Hacking'e girmediğiniz sürece ve/veya taşınabilirlikle ilgili olarak çok fazla endişelenmediğiniz sürece, bu tür ayrıntılara güvenmemek ya da bunlara bağlı kalmak en iyisidir.

0

bir derleyici kodunuzu uygulamak hangi bir şekilde ortaya çıkarır aşağıdaki yeniden yazımını düşünün:

geçersiz 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 ana() {
yapı __vars_main { int i; } * __ stackframe_main = malloc (sizeof (int));

stackDirection(&(__stackframe.i)); 

}

Sen __stackframe_stackDirection ve __stackframe_main esasen rastgele olacağını kabul etmek gerekir. Yığın yukarı veya aşağı büyüyebilir.

Daha da kötüsü, bir lineair modeli varsayıyorsunuz. Ya a<b, b<a, or a==b. Ancak işaretçiler için bu geçerli değildir. Üç karşılaştırmanın tümü a<b, b<a and a==b aynı anda yanlış olabilir.