Valgrind 调试日志:大小为 8 的无效读取 [英] Valgrind debug log: Invalid read of size 8

查看:16
本文介绍了Valgrind 调试日志:大小为 8 的无效读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我决定用 valgrind 调试我的应用程序.我已经解决了很多错误,但不能解决这个问题.

recently I decide to debug my application with valgrind. I've resolved a lot of errors, but can't this one.

==12205== Invalid read of size 8
==12205==    at 0x37E1864C40: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib64/libstdc++.so.6.0.8)
==12205==    by 0x40393C: readConfig(std::string) (stl_tree.h:257)
==12205==    by 0x4058BE: main (application.cpp:42)
==12205==  Address 0x5589b88 is 24 bytes inside a block of size 48 free'd
==12205==    at 0x4A05A33: operator delete(void*) (vg_replace_malloc.c:346)
==12205==    by 0x4067AD: std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::erase(std::_Rb_tree_iterator<std::pair<std::string const, std::string> >, std::_Rb_tree_iterator<std::pair<std::string const, std::string> >) (new_allocator.h:94)
==12205==    by 0x406841: std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::erase(std::string const&) (stl_tree.h:1215)
==12205==    by 0x403934: readConfig(std::string) (stl_map.h:461)
==12205==    by 0x4058BE: main (application.cpp:42)

我的部分代码:

string config_file;
if (strlen(getParam("config") . c_str()) > 0)
{
    config_file = getParam("config");
}
else
    config_file = string("default.conf");
if (access(config_file . c_str(), 0) == -1)
{
    printf("Config file \"%s\" not exists\n", config_file . c_str());
    exit(1);
}
if (!readConfig(config_file))
{
    printf("Application error: read config file\n");
    exit(1);
}

字符串 #42:

if (!readConfig(config_file))

请尝试帮助我.

提前致谢!

更新 #1:

我为这么大的功能道歉:(

I apologize for so large function :(

bool readConfig(string filename)
{
 time_t rawtime;
 struct tm * timeinfo;
 time ( &rawtime );
 timeinfo = localtime ( &rawtime );
 map<string,string> tmp_buff;

  ifstream ifs( filename.c_str() );
   string temp,tmp;
   int i;
   unsigned int MAX_MATCH = 40;
   regex_t re;
   char *pattern = "([^=]+)=(.+)";

   const char* s;
   map<int,string> matches_tmp;
   map<string,string>::const_iterator it;
   char s1[1024];
   size_t rm;
   regmatch_t pmatch[MAX_MATCH];
   regcomp(&re, pattern, REG_ICASE|REG_EXTENDED|REG_NOSUB);
   if ((rm = regcomp (&re, pattern, REG_EXTENDED)) != 0)
    {
      printf("Invalid expression:'%s'\n",pattern);
      return false;
    }
   int start[2]={0},end[2]={0},current[2]={0};
   char * b;
   string substr;
   bool start_time=false,inside_time=false,error=false;

  while( getline( ifs, temp ) )
  {
      tmp=trim(temp);
      tmp=temp;
      if(strlen(tmp.c_str())==0) continue;
      s=tmp.c_str();


      if(!regexec(&re, s, MAX_MATCH, pmatch, 0))
      {
         for(i=1;i<=2;i++)
         {
            strncpy (s1, s + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so);
            s1[pmatch[i].rm_eo - pmatch[i].rm_so] = '\0';
            matches_tmp[i]=trim((string)s1);
         }

         if(matches_tmp[1]==string("start-time"))
         {
            substr=matches_tmp[2].substr(0,2);
            b=new char[substr.length()+1];
            strcpy(b, substr.c_str() );


            if(strlen(b)!=2) continue;
            start[0]=atoi(b);
            //free(b);

            substr=matches_tmp[2].substr(3,2);
            b=new char[substr.length()+1];
            strcpy(b, substr.c_str() );

            if(strlen(b)!=2) continue;
            start[1]=atoi(b);
            start_time=true;
            continue;
         }

         if(matches_tmp[1]==string("end-time"))
         {
            start_time=false;

            substr=matches_tmp[2].substr(0,2);
            b=new char[substr.length()+1];
            strcpy(b, substr.c_str() );


            if(strlen(b)!=2) error=true;
            end[0]=atoi(b);

            substr=matches_tmp[2].substr(3,2);
            b=new char[substr.length()+1];
            strcpy(b, substr.c_str() );

            if(strlen(b)!=2) error=true;
            end[1]=atoi(b);


            if(error)
            {
               printf("ERROR1\n");
               error=false;
               continue;
            }

            current[0]=timeinfo->tm_hour;
            current[1]=timeinfo->tm_min;

            if(end[0]<start[0])
            {
               if(
                     (current[0]<start[0] && current[0]>end[0]) ||
                     (current[0]==start[0] && current[1]<start[1]) ||
                     (current[0]==end[0] && current[1]>end[1])
                 )
                 {
                     error=true;
                 }
            }else
            {
               if(
                     (current[0]<start[0]) ||
                     (current[0]>start[0] && current[0]>end[0]) ||
                     (current[0]==start[0] && current[1]<start[1]) ||
                     (current[0]==end[0] && current[1]>end[1])
                  )
               {
                  error=true;
               }
            }

            if(error)
            {
               error=false;
               continue;
            }

            for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
            {
               if(config.find( it->first ) != config.end()) config.erase(it->first);
               config[it->first]=it->second;
               tmp_buff.erase(it->first);
            }

         }
         if(strlen(matches_tmp[1].c_str())==0) continue;
         if(start_time)
         {
            tmp_buff[matches_tmp[1]]=matches_tmp[2];
         }
         else
            config[matches_tmp[1]]=matches_tmp[2];
      }
  }
}

推荐答案

我想您正在增加一个无效的 std::setstd::map 迭代器.这个不正确的程序产生了类似的 valgrind 错误:

I suppose you are incrementing an invalid std::set or std::map iterator. This incorrect program produces a similar valgrind error:

#include <set>

int main () {
  std::set<int> s;
  s.insert(1);
  s.insert(2);
  s.insert(3);

  for(std::set<int>::iterator it = s.begin(); it != s.end(); ++it) {
    if(*it == 2) s.erase(it);
  }
}

<小时>编辑:是的,你完全按照我说的去做:


EDIT: Yep, you are doing exactly what I said:

     for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
     {
       if(config.find( it->first ) != config.end()) config.erase(it->first);
       config[it->first]=it->second;
       tmp_buff.erase(it->first);
     }

tmp_buff.erase(it->first) 的调用使 it 无效.但是,您随后会增加它:++it.这是不允许的.

The call to tmp_buff.erase(it->first) invalidates it. But, you subsequently increment it: ++it. This is not allowed.

此外,没有理由调用 config.erase.config 中的条目在下一行被覆盖时将被隐式销毁.试试:

Also, there is no reason to call config.erase. The entry in config will be implicity destroyed when it is overwritten in the next line. Try:

     for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
     {
       config[it->first]=it->second;
     }
     tmp_buff.clear();

这篇关于Valgrind 调试日志:大小为 8 的无效读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆