Вопрос

I am having a lot of error valgrind when I'm trying to search and replace some data in a string using boost::regex. I'm getting the correct output but I'm a bit scared of this errors

The thing funny it's that when I comment the line with the replace I'm not getting any errors coming from the line with the search.

So I have the following function

  static void    replaceVar(std::string & input, std::map<std::string, TEMPLATE_PARAM> &param)
  {
    boost::regex ex(REGEX_TAG);
    boost::match_results<std::string::const_iterator> extend;
    std::string::const_iterator start, end;
    boost::match_flag_type flags;

    start = input.begin();
    end = input.end();
    flags = boost::match_default;
    while (boost::regex_search(start, end, extend, ex, flags)) // line 78
      {
        try
          {
            const std::string *ptr = tools::visitor_fct<std::string>(param.at(extend[1])); // this line is working fine
            if (ptr != nullptr)
              input = boost::regex_replace(input, ex, *ptr, boost::match_default | boost::format_first_only); //line 84
          }
        catch (const std::out_of_range& err)
          {
            input = boost::regex_replace(input, ex, std::string(""), boost::match_default | boost::format_first_only);
          }
        start = extend[0].second;
        end = input.end();
        flags |= boost::match_prev_avail;
        flags |= boost::match_not_bob;
      }
  }

I'm getting the following output from valgrind

==21743== Thread 2:
==21743== Invalid read of size 1
==21743==    at 0x54C24B0: boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::find_restart_any() (in /usr/local/lib/libboost_regex.so.1.53.0)
==21743==    by 0x54D83BA: boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::find_imp() (in /usr/local/lib/libboost_regex.so.1.53.0)
==21743==    by 0x4BADB7: bool boost::regex_search<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(__gnu_cxx::__normal_iterator<char const*, std::string>, __gnu_cxx::__normal_iterator<char const*, std::string>, boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, __gnu_cxx::__normal_iterator<char const*, std::string>) (regex_search.hpp:56)
==21743==    by 0x4F40D7: bool boost::regex_search<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(__gnu_cxx::__normal_iterator<char const*, std::string>, __gnu_cxx::__normal_iterator<char const*, std::string>, boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) (regex_search.hpp:42)
==21743==    by 0x4F2BB4: ... line 78

and

==21743==  Address 0x6543315 is 197 bytes inside a block of size 293 free'd
==21743==    at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21743==    by 0x57EBC12: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==21743==    by 0x4F2B0C: (l:84)

I think it's at the assignment that create all this errors because when I put only

boost::regex_replace(input, ex, *ptr, boost::match_default | boost::format_first_only); //line 84

I don't get any valgrind errors

I have also tried to create a new string from the output of regex_replace and then assign it to ouput but I'm still getting this errors

Any ideas ?

Это было полезно?

Решение

To remove all this errors valgrinds I just had to restart the loop each at each change because the end and the begin of the string wasn't the same.

So I just changed the loop to

 bool flag = true;
 while (flag)
  {
    flag = false;
    start = input.begin();
    end = input.end();
    while (boost::regex_search(start, end, extend, ex, boost::match_default))
      {
        try
          {
            const std::string *ptr = tools::visitor_fct<std::string>(param.at(extend[1]));
            if (ptr != nullptr)
              input = boost::regex_replace(input, ex, *ptr, boost::match_default | boost::format_first_only);
          }
        catch (const std::out_of_range& err)
          {
            input = boost::regex_replace(input, ex, std::string(""), boost::match_default | boost::format_first_only);
          }
        flag = true;
        break;
      }
  }

and everything works fine.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top