0

I have an exception in this code

Date & Date::operator=(const std::string & str){
    if (str.size() != 10)
       throw std::exception("not a date");


    std::regex r;// exception here
    try { // exception here
        std::regex regEx ("^[0-9]{4}[0-9]{2}[0-9]{2}");
    }
    catch (std::exception &e) {
        e.what();
    }
    std::regex delims("([^.,;-]+)");

    std::smatch match;
    if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
        std::stringstream ss;
        std::string tmp(match.str());
        std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
        std::sregex_token_iterator(),
        std::ostream_iterator<std::string>(ss, "\n"));
        ss >> year;
        ss >> month;
        ss >> day;
    }
    return *this;
}

If I put similar code in main function in works normaly. I use Visual studio 2015 Community Edition.

4
  • What is the exception? Commented Nov 7, 2015 at 7:28
  • There was an unhandled exception at 0x77383E28 in Test.exe: exception of Microsoft C ++: std :: exception of memory address 0x00C7FAF4 Commented Nov 7, 2015 at 7:35
  • Sorry, but that code makes little sense. For example, you declare the regEx variable in a scope (try/catch) and then use it in an outer scope, where it is not defined. Please post code that can compile. Commented Nov 7, 2015 at 7:50
  • Just comment all code after catch block. I have an exception even at that case. Commented Nov 7, 2015 at 7:56

1 Answer 1

1

Your exception doesn't happen when building the regex but when you throw your own.

First you are checking that your string is exactly 10 characters long. If you put a string of size 10 in your string everything works as it should:

int main()
{
    std::string str = "20151107AB";
    int year = 0;
    int month = 0;
    int day= 0;

    if (str.size() != 10)
        throw std::exception("not a date");

    std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
    std::regex delims("([^.,;-]+)");

    std::smatch match;
    if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
        std::stringstream ss;
        std::string tmp(match.str());
        std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
            std::sregex_token_iterator(),
            std::ostream_iterator<std::string>(ss, "\n"));
        ss >> year;
        ss >> month;
        ss >> day;
    }
} 

If you remove the "AB" you'll get the error as described in your question.

int main()
{
    std::string str = "20151107";
    int year = 0;
    int month = 0;
    int day= 0;

    if (str.size() != 10)
        throw std::exception("not a date");

    std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
    std::regex delims("([^.,;-]+)");

    std::smatch match;
    if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
        std::stringstream ss;
        std::string tmp(match.str());
        std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
            std::sregex_token_iterator(),
            std::ostream_iterator<std::string>(ss, "\n"));
        ss >> year;
        ss >> month;
        ss >> day;
    }
}

If you now remove the length-check everything is working as it should again.

int main()
{
    std::string str = "20151107";
    int year = 0;
    int month = 0;
    int day= 0;

    std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
    std::regex delims("([^.,;-]+)");

    std::smatch match;
    if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
        std::stringstream ss;
        std::string tmp(match.str());
        std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
            std::sregex_token_iterator(),
            std::ostream_iterator<std::string>(ss, "\n"));
        ss >> year;
        ss >> month;
        ss >> day;
    }
}

Also, if you catch the exception everything is still fine (yet the code isn't executed)

int main()
{
    try
    {
        std::string str = "20151107";
        int year = 0;
        int month = 0;
        int day = 0;

        if (str.size() != 10)
            throw std::exception("not a date");

        std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
        std::regex delims("([^.,;-]+)");

        std::smatch match;
        if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
            std::stringstream ss;
            std::string tmp(match.str());
            std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
                std::sregex_token_iterator(),
                std::ostream_iterator<std::string>(ss, "\n"));
            ss >> year;
            ss >> month;
            ss >> day;
        }
    }
    catch (std::exception& e)
    {
        //handle
    }
}

So my assumption on this is that you don't catch the exception anywhere, which might cause memory corruption as the standard doesn't define whether that stack must be unwound in this case.

I would recommend to 1. read Does it make sense to catch exceptions in the main(...)? 2. correctly catch the exception thrown by Date::operator=

Maybe you also want to install a global exception handler (to safely shutdown your program).

And one other thing: Why do you check the length of your date string being exactly 10, when you only need 8 characters?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.