2012-03-27 2 views
3

최근에 valgrind를 사용하여 응용 프로그램을 디버깅하기로 결정했습니다. 많은 오류를 해결했지만 해결할 수 없습니다. 내 코드의Valgrind 디버그 로그 : 크기가 8보다 작습니다.

==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 :. 내가 너무 많은 기능 :(

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]; 
     } 
    } 
} 
+2

'의 나 strlen (getParam를 ("설정") c_str()을'왜'getParam ("설정") 크기()' –

+0

당신은'readConfig() '함수 정의가 게시 할 수 있습니까?이 ? – hmjd

+2

최적화를 비활성화하면 ('-O0'로 컴파일) getter backtrace를 얻을 수 있습니다. 일부 함수가 인라인되어있는 것처럼 보입니다.이 경우 백 트레이스에 표시되지 않습니다. –

답변

9

내가 잘못된 std::set 또는 std::map 반복자를 증가한다고 가정에 대해 사과

이 잘못된 프로그램은 유사한 Valgrind의 오류가 발생합니다 :

#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); 
    } 
} 


편집 :

 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. 허용되지 않습니다.

또한 config.erase으로 전화 할 이유가 없습니다. config에있는 항목은 다음 행에 겹쳐 쓰여질 때 암시 적으로 손상됩니다. 시도해보십시오.?.

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