0

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

4

2 回答 2

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()(如果没有内存重新分配,否则你有悬空指针)。

于 2013-06-06T10:00:37.753 回答
1

您不能将结果存储c_strservice[i]:c_str中,一旦您对string从中提取c_str(). 如果您必须有一个 C 字符串,请使用strdup;进行复制。否则,请使用它std::string来简化您的内存管理。

此外,将c_str()其用作目的地strcpy错误的。你抛弃 const-ness 的事实(char*)pick.c_str()应该清楚地表明你所做的事情是不正确的。如果要将一个字符串复制到另一个字符串中,则可以使用赋值运算符。

于 2013-06-06T10:01:44.003 回答