Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++98 string concatenation with c_str() return

I wanted to create a custom exception by concatonating a string before returning it on what(). I am aware of other ways to achive the wanted result, i just want to undertand why the 3 following pieces of code are behaving differently.

class InvalidFormat : public std::exception
{
    private:
        std::string _exceptionValue;
    public:
        InvalidFormat(std::string str);
        const char *what() const throw();
};

InvalidFormat::InvalidFormat(std::string str) : _exceptionValue(str) {}

const char *InvalidFormat::what() const throw() {
return ("Format is invalid => " + _exceptionValue).c_str();}
//doesn't output anything
InvalidFormat::InvalidFormat(std::string str) : _exceptionValue(str) {}

const char *InvalidFormat::what() const throw() {
return std::string("Format is invalid => ").assign(_exceptionValue).c_str();}
//outputs random data
InvalidFormat::InvalidFormat(std::string str) : _exceptionValue("Format is invalid => " + str) {}

const char *InvalidFormat::what() const throw() {
return _exceptionValue.c_str();}
//outputs is correct

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The following calls c_str() on a temporary std::string whose life ends after the full expression (at the ;):

return ("Format is invalid => " + _exceptionValue).c_str(); // UB-prone

When InvalidFormat::what() returns, the returned pointer points to memory freed and gone, which is undefined behaviour. This is no better:

return std::string("Format is invalid => ").assign_exceptionValue).c_str(); // UB-prone

You must store the result of the concatenation if you want to return a non-owning pointer to it:

InvalidFormat::InvalidFormat(std::string str)
    : _exceptionValue("Format is invalid => " + str)
{}

const char *InvalidFormat::what() const throw()
{
    return _exceptionValue.c_str(); // OK
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading