Visual Studio (Dinkumware?) Utiliza una implementación de std::exception
que contiene † almacenamiento interno para el mensaje. (Completo con un constructor no estándar que acepta una cadena).
Debido a esto, no se necesita ningún despacho virtual para obtener el mensaje de error, ya que sobrevive a cualquier división.
Una implementación más ortodoxa de hecho imprimiría un mensaje de excepción genérico, porque el objeto derivado se cortó. (Efectivamente, MS ha hecho std::exception
y std::runtime_error
equivalente. No hay nada malo con esto, ya que el valor de retorno de std::exception::what
es definido por la implementación, sino que explica sus resultados.)
† almacenamiento interno aquí se utiliza libremente. No tiene un buffer interno , pero tiene un const char*
y un bool
. El const char*
apunta al mensaje (el valor de retorno de what()
) y el bool
es un indicador que determina si el búfer debe eliminarse.
Es como esto:
class msvc_exception // for exposition
{
public:
msvc_exception(const char* msg) :
mMsg(msg),
mDoDelete(false)
{}
msvc_exception(const std::string& msg) :
mMsg(copy_string(msg)),
mDoDelete(true)
{}
virtual ~msvc_exception()
{
if (mDoDelete)
delete [] mMsg;
}
virtual const char* what() const throw()
{
return mMsg ? mMsg : "unknown";
}
private:
const char* copy_string(const std::string& str)
{
const char* result = new char[str.size() + 1];
std::copy(str.begin(), str.end(), result);
result[str.size()] = 0; // null-terminate
return result;
}
};
Ahora vemos que bad_alloc
funciona así:
class msvc_bad_alloc : // for exposition
public msvc_exception
{
public:
msvc_bad_alloc() :
msvc_exception("bad_alloc") // note: a static string, no dynamic storage
{}
};
rebanar no afecta el mensaje porque el mensaje "existe" en la clase base.
Otros compiladores, como GCC y LLVM, aplicar un poco más recto hacia delante:
class orthodox_exception
{
public:
orthodox_exception(){}
virtual ~orthodox_exception() {}
virtual const char* what() const throw()
{
return "orthodox_exception";
}
};
class orthodox_bad_alloc :
public orthodox_exception
{
public:
const char* what() const throw()
{
return "orthodox_bad_alloc";
}
};
Aquí, rebanar afectaría a su resultado. (Dicho esto, después de todo esto: siempre capturas por referencia.)
Acabas de tratar de asignar = ~ 1.9375GB en tu programa. ¿Estás compilando 32 bits? ¿Tienes tanta RAM en tu máquina? – FailedDev
@GMan El compilador es MS VS 2008 – Belloc