pilas - Corrupción de pila en C++
pilas y colas en c++ (6)
- Podría tener un puntero aleatorio / indefinido que termine apuntando a la pila, y escribir eso.
- Una función de ensamblaje podría configurar / modificar / restaurar incorrectamente la pila
- Las ondas cósmicas podrían voltear bits en la pila.
- Los elementos radiactivos en la carcasa del chip podrían voltear bits.
- Cualquier cosa en el kernel podría salir mal y cambiar accidentalmente su memoria de pila.
Pero esos no son específicos de C ++, que no tiene idea de la pila.
En C ++, de qué manera la pila puede corromperse. Una forma que supongo es sobrescribir las variables de la pila al acceder a una matriz más allá de sus límites. ¿Hay alguna otra forma de que pueda corromperse?
El estándar de C ++ no define la pila / montón. Además, hay varias formas de invocar un comportamiento indefinido en un programa, todo lo cual puede dañar tu pila (después de todo, es UB). La respuesta corta es: su pregunta es demasiado vaga para tener una respuesta significativa.
Lanzar una excepción dentro de un destructor es un buen candidato. Sería desordenar el despliegue de la pila.
Las violaciones de la Regla de una definición pueden llevar a la corrupción de la pila. El siguiente ejemplo parece estúpido, pero lo he visto un par de veces con diferentes bibliotecas compiladas en diferentes configuraciones.
header.h
struct MyStruct
{
int val;
#ifdef LARGEMYSTRUCT
char padding[16];
#endif
}
archivo1.cpp
#define LARGEMYSTRUCT
#include "header.h"
//Here it looks like MyStruct is 20 bytes in size
void func(MyStruct s)
{
memset(s.padding, 0, 16); //corrupts the stack as below file2.cpp does not have LARGEMYSTRUCT declared and declares Mystruct with 4 bytes
return; //Will probably crash here as the return pointer has been overwritten
}
file2.cpp
#include "header.h"
//Here it looks like MyStruct is only 4 bytes in size.
extern void func(MyStruct s);
void caller()
{
MyStruct s;
func(s); //push four bytes on to the stack
}
Llamar a una función con la convención de llamada incorrecta.
(aunque esto es técnicamente específico del compilador, no es una cuestión de C ++, cada compilador de C ++ tiene que lidiar con eso).
Tomar punteros para apilar variables es una buena manera:
void foo()
{
my_struct s;
bar(&s);
}
Si la barra mantiene una copia del puntero, cualquier cosa puede pasar en el futuro.
Resumiendo: la corrupción de la pila ocurre cuando hay punteros perdidos que apuntan a la pila.