来看这个代码
#include <iostream> #include <string> #include <map> std::map<std::string, std::string> mapHttpRequest; std::string GetString(std::string strKey) { std::map<std::string, std::string>::iterator it = mapHttpRequest.find(strKey); if (it != mapHttpRequest.end()) { return it->second; } return ""; } int SplitString() { std::string strUrlParamValue = GetString("l"); std::cout<<"before: "<<strUrlParamValue<<std::endl; char *pInOuter; char* p = strtok(const_cast<char*>(strUrlParamValue.c_str()), "|_"); while (p) { std::cout<<"-> "<<p<<std::endl; p = strtok(NULL, "|_"); } std::cout<<"after: "<<strUrlParamValue<<std::endl; return 0; } int main() { mapHttpRequest["l"] = "4001|4002"; SplitString(); SplitString(); return 0; }
一般理解,连续调用两次 split string 函数,输出应该是完全一致的吧,嗯,来看结果
before: 4001|4002 -> 4001 -> 4002 after: 40014002 before: 40014002 -> 4001 after: 40014002
环境是 linux 2.6.16 64bit,gcc 的版本是 4.1.2
不过,在 vs 2005 下跑这个代码,得到的输出确实这样的
before: 4001|4002 -> 4001 -> 4002 after: 4001 4002 before: 4001|4002 -> 4001 -> 4002 after: 4001 4002
嗯,这个跟想象中的差不多吧
把细节打出来看看呗
#include <iostream> #include <string> #include <map> std::map<std::string, std::string> mapHttpRequest; std::string GetString(std::string strKey) { std::map<std::string, std::string>::iterator it = mapHttpRequest.find(strKey); if (it != mapHttpRequest.end()) { std::cout<<"map value addr: "<<(void*)it->second.c_str()<<std::endl; return it->second; } return ""; } int SplitString() { std::string strUrlParamValue = GetString("l"); std::cout<<"get string func return addr: "<<(void*)strUrlParamValue.c_str()<<std::endl; std::cout<<"before: "<<strUrlParamValue<<std::endl; char *pInOuter; char* p = strtok(const_cast<char*>(strUrlParamValue.c_str()), "|_"); while (p) { std::cout<<(void*)p<<" -> "<<p<<std::endl; p = strtok(NULL, "|_"); } std::cout<<"after: "<<strUrlParamValue<<std::endl; return 0; } int main() { mapHttpRequest["l"] = "4001|4002"; SplitString(); SplitString(); return 0; }
先看 linux 下的结果
map value addr: 0x504098 get string func return addr: 0x504098 before: 4001|4002 0x504098 -> 4001 0x50409d -> 4002 after: 40014002 map value addr: 0x504098 get string func return addr: 0x504098 before: 40014002 0x504098 -> 4001 after: 40014002
再看 vs 2005 的执行结果
map value addr: 005D345C get string func return addr: 0018FDF8 before: 4001|4002 0018FDF8 -> 4001 0018FDFD -> 4002 after: 4001 4002 map value addr: 005D345C get string func return addr: 0018FDF8 before: 4001|4002 0018FDF8 -> 4001 0018FDFD -> 4002 after: 4001 4002
其中的原因,有可能是编译器的返回值优化,也有可能是 stl 的各自实现不同,现在过年了,没心情细究啊。。