c++ - Cuando una clase se asigna dinámicamente en el constructor, ¿por qué ocurre un desbordamiento de pila en lugar de std:: bad_alloc?
stack-overflow bad-alloc (3)
El desbordamiento de pila está ocurriendo porque tienes una recursión infinita.
Llamar al
Overflow()
hace que llames al
Overflow()
una y otra vez.
Esas llamadas de función deben ir en la pila.
Debido a que su pila es más pequeña que su montón, se quedará sin espacio en la pila para todas esas llamadas de constructor antes de quedarse sin memoria para todos los objetos que está creando.
Hice una clase que se crea de forma recursiva utilizando
new
(¡solo por diversión!), Esperando que esto
std::bad_alloc
debido a una asignación dinámica infinita (desbordamiento de pila).
Pero el desbordamiento de pila ocurrió en lugar de
std::bad_alloc
.
¿Por qué pasó esto?
class Overflow
{
private:
Overflow* overflow;
public:
Overflow()
{
overflow = new Overflow();
}
};
int main()
{
Overflow overflow_happens; // stack overflow happens instead of std::bad_alloc exeption
}
@Caleth preguntó qué sucede si cambio nuevo Desbordamiento () a nuevo Desbordamiento [100000], y esto me dio
std::bad_alloc
.
De acuerdo con las respuestas, ¿no debería esto también darme un desbordamiento de pila?
Hice una pequeña modificación a tu código:
#include <array>
template <size_t size>
class Overflow
{
private:
Overflow* overflow;
std::array<int,size> x;
public:
Overflow()
{
overflow = new Overflow();
}
};
En la wandbox esto
int main()
{
Overflow<1> overflow_happens;
}
da como resultado un fallo de segmentación causado por el desbordamiento de la pila.
Sin embargo, this
int main()
{
Overflow<10000> bad_alloc;
}
resultados en
terminate called after throwing an instance of ''std::bad_alloc''
what(): std::bad_alloc
Aborted
Básicamente tienes dos efectos que compiten aquí. Como primera aproximación (los detalles son un poco más complicados) tiene para cada recursión del consturctor:
-
un
Overflow*
en la pila -
toda una instancia de
Overflow
en el montón
Por lo tanto, si primero obtiene un desbordamiento de pila o
bad_alloc
depende del tamaño del
Overflow
.
Y para tamaños pequeños primero obtendrá un desbordamiento, porque el espacio de pila es mucho más limitado que el espacio de pila.
PD:
me perdí su edición ... si coloca un
new Overflow[100000]
en el constructor en su código, amplifica el espacio de almacenamiento requerido, al igual que lo hice al agregar el miembro de la
array
.
En la pila todavía tienes un solo puntero y, por lo tanto, te quedas sin pila mucho antes.
Porque estás recursivamente llamando al constructor, a un método, repetidamente. El método llama a la pila de llamadas. Como el tamaño de pila es mucho más pequeño que el montón disponible, la pila de llamadas se desborda antes de que se agote el montón.