C++ Valgrind调试日志:大小为8的读取无效
最近我决定用valgrind调试我的应用程序。 我已经解决了很多错误,但不能解决这个问题C++ Valgrind调试日志:大小为8的读取无效,c++,valgrind,C++,Valgrind,最近我决定用valgrind调试我的应用程序。 我已经解决了很多错误,但不能解决这个问题 ==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_tr
==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)
字符串#42:
请试着帮助我
提前谢谢
更新#1:
我为这么大的功能道歉:(
bool readConfig(字符串文件名)
{
时间与时间;
结构tm*时间信息;
时间(&rawtime);
timeinfo=localtime(&rawtime);
地图tmp_buff;
ifstream ifs(filename.c_str());
字符串温度,tmp;
int i;
无符号整数最大匹配=40;
正则表达式;
char*pattern=“([^=]+)=(.+)”;
常量字符*s;
地图匹配(tmp),;
map::const_迭代器it;
字符s1[1024];
大小;;
regmatch_t pmatch[最大匹配];
注册会计师(注册会计师、注册会计师、注册会计师、注册会计师、扩展会计师、注册会计师);
如果((rm=regcomp(&re,模式,REG_扩展))!=0)
{
printf(“无效表达式:“%s”\n”,模式);
返回false;
}
int开始[2]={0},结束[2]={0},当前[2]={0};
char*b;
字符串substr;
bool start_time=false,inside_time=false,error=false;
while(getline(ifs,temp))
{
tmp=微调(温度);
tmp=温度;
如果(strlen(tmp.c_str())==0)继续;
s=tmp.c_str();
如果(!regexec(&re,s,MAX_MATCH,pmatch,0))
{
对于(i=1;itm_小时;
当前[1]=timeinfo->tm\u min;
如果(结束[0]结束[0])||
(当前[0]==开始[0]&当前[1]结束[1])
)
{
错误=真;
}
}
如果(错误)
{
错误=错误;
继续;
}
for(it=tmp_buff.begin();it!=tmp_buff.end();+it)
{
如果(config.find(it->first)!=config.end())config.erase(it->first);
配置[it->first]=it->second;
tmp_buff.erase(它->第一个);
}
}
如果(strlen(matches_tmp[1].c_str())==0)继续;
如果(开始时间)
{
tmp_buff[matches_tmp[1]]=matches_tmp[2];
}
其他的
config[matches_tmp[1]]=matches_tmp[2];
}
}
}
我想您正在递增一个无效的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);
}
}
调用tmp\u buff.erase(it->first)
会使无效,但随后会增加它:++it
。这是不允许的
此外,没有理由调用config.erase
。config
中的条目在下一行被覆盖时将被隐式销毁。请尝试:
for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
{
config[it->first]=it->second;
}
tmp_buff.clear();
strlen(getParam(“config”).c_str()
?为什么不getParam(“config”).size()
?可以发布readConfig()
函数定义吗?如果禁用优化(使用-O0
编译),可能会得到一个getter回溯。看起来有些函数已经内联,在这种情况下,它们不会显示在回溯中。在我看来,您在使std::set
或std::map
迭代器无效后正在递增该迭代器。虽然回溯确实表明错误在readConfig
内,但看起来您正在递增迭代器或者在它引用的map元素被擦除之后,使迭代器无效。
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];
}
}
}
#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);
}
for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
{
config[it->first]=it->second;
}
tmp_buff.clear();