2010-08-26 8 views
6

Por lo tanto, de mi pregunta memmove anterior me gustaría saber cómo encontrar la dirección del crecimiento de la pila.dirección de crecimiento de la pila

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

¿Y su código no funciona, o dónde está el problema? – nothrow

+0

El problema es que no puedo decir si este código es correcto – brett

+0

una prueba mejor sería llamadas _alloca secuenciales, ya que los punteros de la pila estarían en el mismo marco de la pila y no estarían sujetos a optimizaciones del compilador – Necrolis

Respuesta

13

Es posible que la pila no crezca ni disminuya.

Cada marco de pila se puede asignar potencialmente en puntos aleatorios dentro del montón.
Esto se hace en realidad en varios sistemas operativos para tratar de evitar la destrucción de la pila por código malicioso. El concepto de una pila creciendo hacia el montón es solo una manera fácil de enseñar el concepto de una pila (y por supuesto, las primeras implementaciones funcionaron de esta manera ya que era simple (no hay necesidad de hacer algo más difícil de lo que necesitabas). nadie está tratando de romperte)).

+0

@Martin Stack se crea en el montón? No lo entiendo? OS separa la pila del montón a la derecha y los divide en páginas ¿verdad? ¿Cómo puede esto ser dependiente de la arquitectura? Porque a lo que me refiero aquí es a las direcciones lógicas correctas y estas direcciones lógicas son solo dependientes del compilador ¿no? – brett

+0

@Brett: desde la perspectiva del hardware, toda la memoria es solo memoria. El sistema operativo puede elegir hacer lo que quiera. – Potatoswatter

+1

@brett: En la antigüedad, la pila y el montón eran entidades separadas y conceptualmente crecían entre sí. Pero esto fue bastante fácil de corromper y causar la ejecución de código malicioso. Entonces algunas personas inteligentes pensaron un poco. Ahora, una pila es solo una serie de marcos (uno para cada llamada de función). No hay ninguna razón técnica por la que necesiten ir uno tras otro (ya que el actual tiene un enlace de regreso al último). Entonces, ¿por qué no asignar los cuadros de pila en el montón utilizando las rutinas normales de administración de memoria? Conceptualmente: Desenrollar la pila libera el cuadro actual y sigue la cadena hacia atrás. –

0

Su función depende del parámetro int * que puede apuntar a cualquier lugar, y también ser NULL. Es mejor comparar direcciones de dos variables locales.

+0

El compilador puede asignar variables locales en cualquier orden. Sí, construirá y destruirá en el orden correcto, pero puede asignar espacio para ellos donde quiera. – sharptooth

1

Experimentos como este no son confiables, porque puede encontrarse con excepciones. El optimizador puede arruinarte o el sistema puede usar registros para parámetros. Si realmente debe saber la dirección de la pila, lea el manual de su procesador.

No obstante, a menos que esté escribiendo un sistema operativo o algo realmente de bajo nivel, si necesita saber la dirección de la pila probablemente esté haciendo algo feo y horrible y realmente debería reconsiderar sus métodos.

0

Esto está fuera del alcance del estándar C++. Es un comportamiento definido por la implementación y probablemente dependa de la arquitectura del sistema operativo/procesador específico, etc.

Es mejor no confiar o depender de tales detalles, a menos que esté en hacking ETHICAL :) y/o no tanto por la portabilidad

0

Considere lo siguiente reescritura, que expone de una manera en la que un compilador puede implementar su código:

vacío 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)); 

}

Vas a tener que aceptar que __stackframe_stackDirection y __stackframe_main habrá esencialmente aleatoria. La pila puede crecer hacia arriba o hacia abajo.

Peor aún, usted está asumiendo un modelo linealir. O bien a<b, b<a, or a==b. Pero para los indicadores esto no se sostiene. Las tres comparaciones a<b, b<a and a==b pueden ser falsas al mismo tiempo.

Cuestiones relacionadas