当我启动valgrind时,一切正常,但从这个错误开始,后面的行开始表现相同(读取无效等)。
Invalid read of size 1
==5134== at 0x4C2BFE7: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5134== by 0x40C553: XAMBO::listing_start(std::string&) (listing.cpp:616)
==5134== by 0x40DAD7: msg_callback(unsigned char*) (msg_callback_act.cpp:263)
其中listing.cpp的功能如下(该函数接受一个字符串并删除逗号,并将结果放入一个数组。我从数组中随机选取结果,并将其放入一个字符串中并返回1字符串结果)
listing_start(string& _string){
string pick, tkn;
size_t pos = 0;
string delimiter = ",";
const char *service[MAX_SERVICE];
int i= 0,random_val= 0;
std::string::iterator e = std::remove(_string.begin(),_string.end(), ' ');
_string.erase(e, _string.end());
while ((pos = _string.find(delimiter))!= std::string::npos) {
tkn = _string.substr(0, pos);
if (!tkn.empty()) service[i] = tkn.c_str();
i++;
_string.erase(0, pos + delimiter.length());
}
service[i] = _string.c_str();
random_val = rand()%i;
strcpy((char*)pick.c_str(), service[random_service]);
return pick;
}
valgrind指向的线是这样的: strcpy((char *)wanted_service.c_str(),service [random_service]);
我无法弄清楚为什么上面一行中的stringcopy不能正常工作(虽然当我打印结果时,我有我想要的东西)。为什么valgrind抱怨,我该如何修复上面的代码?
答案 0 :(得分:3)
strcpy((char*)pick.c_str(), service[random_service]);
这是不正确的。 pick
为空字符串,不应通过c_str
修改字符串内容。
你应该使用
pick = service[random_service];
在这种情况下。
if (!tkn.empty()) service[i] = tkn.c_str();
这是不正确的。在tkn = _string.substr(0, pos);
中的下一个service[i]
将是下一个tkn.c_str()
之后(如果没有内存重新分配,否则你有悬空指针)。
答案 1 :(得分:1)
c_str
中service[i]
的结果无法存储c_str
,只要您对string
进行任何修改,c_str()
就会失效strdup
}}。如果您必须拥有C字符串,请使用std::string
制作副本;否则,使用c_str()
来简化内存管理。
此外,使用strcpy
作为(char*)pick.c_str()
的目标是错误的。你用{{1}}抛弃常数的事实应该清楚地告诉你,你所做的事情是不正确的。如果要将一个字符串复制到另一个字符串中,可以改为使用赋值运算符。