valgrind:在strcpy期间无效读取大小为1

时间:2013-06-06 09:53:01

标签: c++ valgrind

当我启动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抱怨,我该如何修复上面的代码?

2 个答案:

答案 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_strservice[i]的结果无法存储c_str,只要您对string进行任何修改,c_str()就会失效strdup }}。如果您必须拥有C字符串,请使用std::string制作副本;否则,使用c_str()来简化内存管理。

此外,使用strcpy作为(char*)pick.c_str()目标是错误的。你用{{1}}抛弃常数的事实应该清楚地告诉你,你所做的事情是不正确的。如果要将一个字符串复制到另一个字符串中,可以改为使用赋值运算符。