c++ stack-overflow bad-alloc

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.