Std :: exception using message from local object

Is the following code a safe exception throw with a custom message?

#include <exception> #include <sstream> #include <string> #include <iostream> int main() { try { std::ostringstream msg; msg << "give me " << 5; throw std::exception(msg.str().c_str()); } catch (std::exception& e) { std::cout << "exception: " << e.what(); } } 

With VC ++ - 2008 this gives:

 exception: give me 5 

But now I'm wondering why the "give me 5" message from the local msg object is still available in the catch block? By the time of publication of the message, should both the stream and the temporary string object be deleted? Btw: This method of generating a message for an exception, apparently, also works with several functions, as well as if new memory is allocated in the catch block before printing the exception.

Or you need to define your own exception class with the std :: string member in order to safely save the message before printing it. A.

+7
source share
3 answers

It is completely safe. A constructor that takes a C string as a single parameter creates a copy of the string. The constructor, which takes the string C and the length parameter, allows you to specify whether memory is allocated, and stores a pointer to the string (the length parameter is ignored).

Please note that these two constructors are extensions of the std::exception class and are not standard. Also keep in mind that a constructor that takes a C string as one parameter is not marked as explicit.

+5
source

Everything is good.

In ยง15.1 / 3:

Throwing a copy of the exception initializes (8.5, 12.8) a temporary object called the exception object.

and ยง15.1 / 4:

Memory for the object of exclusion is allocated in unspecified, with the exception of cases specified in clause 3.7.4.1. If the handler completes the recovery, control is transferred to another handler for the same exception. the exception object is destroyed after the last active handler to exclude is excluded by any means other than reintronation ...

so after throw expression :

the expression will be copied (a new object will be created by the copy constructor), and you should not worry about the local object.

About msg and const char* you are worried about ... here is the Microsoft implementation:

 exception::exception(const char * const & _What) : _Mywhat(NULL), _Mydofree(false) { _Copy_str(_What); //^^^^^^^^^^^^^^^^^ } void exception::_Copy_str(const char * _What) { if (_What != NULL) { const size_t _Buf_size = strlen(_What) + 1; _Mywhat = static_cast<char *>(malloc(_Buf_size)); if (_Mywhat != NULL) { _CRT_SECURE_STRCPY(const_cast<char *>(_Mywhat), _Buf_size, _What); //^^^^^^^^^^^^^^^^^^ _Mydofree = true; } } } 

It copies _What not only saving the pointer.

+4
source

No, this is not safe, because std::exception does not have a constructor that accepts char * in the standard. You are using the MS extension. To make it portable and safe, use std::runtime_error instead, to which you can pass std::string to ctor.

+3
source

All Articles