2010-08-26 13 views
6

Quindi dalla mia precedente domanda su memmove vorrei sapere come trovare la direzione della crescita dello stack.direzione di crescita dello stack

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

E il tuo codice non funziona, o dov'è il problema? – nothrow

+0

Il problema è che non posso dire se questo codice è corretto – brett

+0

imo un test migliore sarebbe sequenziale _alloca chiamate, come i puntatori dello stack sarebbero nello stesso stack frame, e non sarebbe soggetto ad alcuna ottimizzazione del compilatore – Necrolis

risposta

13

La pila non può crescere o scendere.

Ogni frame dello stack può potenzialmente essere allocato in punti casuali all'interno dell'heap.
Questo in realtà viene eseguito in diversi sistemi operativi per tentare di impedire lo smashing di stack tramite codice dannoso.

Il concetto di stack che cresce verso l'heap è solo un modo semplice per insegnare il concetto di stack (e ovviamente le prime implementazioni hanno funzionato in questo modo in quanto era semplice (non è necessario fare qualcosa di più difficile di quando nessuno sta cercando di romperti)).

+0

@Martin Stack viene creato nell'heap? Lo capisco? OS separa lo stack da heap a destra e li divide in pagine, giusto? Come può essere l'architettura dipendente? Perché quello a cui mi riferisco sono gli indirizzi logici giusti e questi indirizzi logici dipendono solo dal compilatore? – brett

+0

@Brett: dal punto di vista dell'hardware, tutta la memoria è solo memoria. Il sistema operativo può quindi scegliere di fare tutto ciò che vuole. – Potatoswatter

+1

@brett: nei vecchi tempi lo stack e l'heap erano entità separate e concettualmente crescevano l'uno verso l'altro. Ma questo è stato piuttosto facile da corrompere e causare l'esecuzione di codice dannoso. Quindi alcune persone intelligenti hanno pensato un po '. Ora uno stack è solo una serie di frame (uno per ogni chiamata di funzione). Non c'è alcun motivo tecnico per cui debbano andare uno dopo l'altro (poiché quello attuale ha un link che riporta all'ultimo). Quindi, perché non allocare solo i frame dello stack nell'heap utilizzando le normali routine di gestione della memoria. Concettualmente: srotolando lo stack si libera il fotogramma corrente e si segue la catena. –

0

La tua funzione dipende dal parametro int * che può puntare ovunque e anche essere NULL. È meglio confrontare gli indirizzi di due variabili locali.

+0

Il compilatore è libero di allocare variabili locali in qualsiasi ordine. Sì, li costruirà e li distruggerà nel giusto ordine, ma può allocare lo spazio per loro ovunque lo desideri. – sharptooth

1

Esperimenti come questo non sono affidabili, perché è possibile eseguire eccezioni. L'ottimizzatore può rovinarti o il sistema potrebbe utilizzare i registri per i parametri. Se davvero deve conoscere la direzione dello stack, leggere il manuale del processore.

Tuttavia, a meno che non si stia scrivendo un sistema operativo o qualcosa di veramente di basso livello, se è necessario conoscere la direzione dello stack probabilmente si sta facendo qualcosa di brutto e orribile e si dovrebbe davvero riconsiderare i propri metodi.

0

Questo è al di fuori dello scopo dello standard C++. Si tratta di un comportamento definito dall'implementazione e probabilmente dipende dall'architettura specifica del processore/OS ecc.

È preferibile non fare affidamento o dipendere da tali dettagli, a meno che non si sia interessati all'hacking ETHICAL :) e/o non tanto alla portabilità

0

si consideri il seguente riscrittura, che espone un modo in cui un compilatore può implementare il codice:

vuoto 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)); 

}

Dovrete convenire che __stackframe_stackDirection e __stackframe_main sarà essenzialmente casuale. Lo stack può crescere o scendere.

Peggio, state assumendo un modello di linea. O a<b, b<a, or a==b. Ma per i puntatori questo non regge. Tutti e tre i confronti a<b, b<a and a==b potrebbero essere falsi allo stesso tempo.

Problemi correlati