在一个部署上线的程序中,使用了strtok和strdup来做字符串的分割,在开发机以及多台产品环境中均运行良好。
但是当要规模化部署在近20台机器上时,却发现总会在这些部署机器中,随机发生字符串切割后的不准确性。
在问题定位后,抽取了当中的strtok,strdup的字符串分割代码,实现了一个单元测试。结果很令人吃惊,就算在同一台机器上,以同样的输入条件,来重复运行该程序, 总会有几次切割后的字符串不准确。
这个现象很是让人困扰。google和百度后,也没确定性的解释。暂且记下这个问题,以后来详细分析这个现象。
最后的结果还是决定自己实现一个字符串的切割算法,来替换strtok和strdup的使用。
这个新算法在所有的部署机上运行,都是单一的,正确的结果,成功实现部署,验收通过。
原始代码:
vector<char*>* Util::strSplit(char* a_str, const char a_delim)
{
vector<char*> * result = new vector<char*>();
char* token = strtok(a_str, &a_delim);
while (token)
{
result->push_back(strdup(token));
token = strtok(0, &a_delim);
}
return result;
}
更新后的代码:
vector<char*>* Util::strSplit(char* a_str, const char a_delim){
vector<char*> * result = new vector<char*>();
char* head = a_str;
char* temp = a_str;
int idx = 0;
while(*temp != '\0' && temp != NULL){
if(*temp != a_delim){
temp++;
idx ++;
}else{
char* content = (char*)malloc(sizeof(char) * (idx + 1));
strncpy(content, head, idx);
content[idx] = '\0';
result->push_back(content);
idx = 0;
temp++;
head = temp;
}
}
char* content = (char*)malloc(sizeof(char) * (idx + 1));
strncpy(content, head, idx);
content[idx] = '\0';
result->push_back(content);
return result;
}
需要分割的字符串为“:”分隔,大致如下所示:
resourcepool:10.xxx.x.32:9123:cmd heartbeat xxx MAQ-01 xxx :;pdu1,10.xxx.x.130,10086,0,1:cmd reset resourceName-xxx