const char* 指针作为函数参数也能被修改? 如下示例程序所示 首先构建了一个如下所示的Node树,每个节点存有一个数字。程序需要通过node的name返回其数字即findNodeNumByName其中name是const char*表示方法中不会修改其参数。另外这个参数来自于另外一个方法即findNodeNameByNum输入数字找到对应的node的name。所以正确的程序输出应该为输入1输出1输入2输出2输出与输入相同。span stylecolor:#333333span stylebackground-color:#ffffffcode classlanguage-c language-cspan stylecolor:#2b91af#span stylecolor:#0000ffinclude/spanspan stylecolor:#3388aaiostream/span/span span stylecolor:#2b91af#span stylecolor:#0000ffinclude/spanspan stylecolor:#3388aastring/span/span span stylecolor:#2b91af#span stylecolor:#0000ffinclude/spanspan stylecolor:#3388aavector/span/span span stylecolor:#0000ffclass/span span stylecolor:#a31515Node/span { public: Node(span stylecolor:#0000ffstd/span::span stylecolor:#0000ffstring/span s, span stylecolor:#a31515int/span n) { name (span stylecolor:#a31515char/span*)span stylecolor:#0000ffmalloc/span(span stylecolor:#88000010/span); strcpy_s(name, span stylecolor:#88000010/span, s.c_str()); num n; } span stylecolor:#0000ffstd/span::span stylecolor:#0000ffstring/span span stylecolor:#a31515GetName/span() {span stylecolor:#0000ffreturn/span name;} span stylecolor:#a31515const/span span stylecolor:#a31515char/span* span stylecolor:#a31515GetNameCstr/span() {span stylecolor:#0000ffreturn/span name;} span stylecolor:#a31515int/span span stylecolor:#a31515GetNum/span() { span stylecolor:#0000ffreturn/span num; } span stylecolor:#0000ffstd/span::span stylecolor:#0000ffvector/spanNode* span stylecolor:#a31515GetChildNodes/span() {span stylecolor:#0000ffreturn/span childNodes;} span stylecolor:#a31515char/span* name; span stylecolor:#a31515int/span num; span stylecolor:#0000ffstd/span::span stylecolor:#0000ffvector/spanNode* childNodes; }; Node* A, * B, * C, * D, * E, * F, * G, * H; span stylecolor:#a31515void/span span stylecolor:#a31515initializeNodes/span() { A new Node(span stylecolor:#a31515A/span, span stylecolor:#8800000/span); B new Node(span stylecolor:#a31515B/span, span stylecolor:#8800001/span); C new Node(span stylecolor:#a31515C/span, span stylecolor:#8800002/span); D new Node(span stylecolor:#a31515D/span, span stylecolor:#8800003/span); E new Node(span stylecolor:#a31515E/span, span stylecolor:#8800004/span); F new Node(span stylecolor:#a31515F/span, span stylecolor:#8800005/span); G new Node(span stylecolor:#a31515G/span, span stylecolor:#8800006/span); H new Node(span stylecolor:#a31515H/span, span stylecolor:#8800007/span); A-childNodes.push_back(B); A-childNodes.push_back(C); B-childNodes.push_back(D); B-childNodes.push_back(E); B-childNodes.push_back(F); C-childNodes.push_back(G); E-childNodes.push_back(H); } span stylecolor:#a31515const/span span stylecolor:#a31515char/span* span stylecolor:#a31515findNodeNameByNum/span(Node* node, span stylecolor:#a31515int/span num) { span stylecolor:#a31515const/span span stylecolor:#a31515char/span* n node-GetName().c_str(); span stylecolor:#0000ffif/span (node-GetNum() num) span stylecolor:#0000ffreturn/span n; span stylecolor:#0000fffor/span (span stylecolor:#0000ffauto/span* n : node-GetChildNodes()) { span stylecolor:#a31515const/span span stylecolor:#a31515char/span* result findNodeNameByNum(n, num); span stylecolor:#0000ffif/span (result ! nullptr) span stylecolor:#0000ffreturn/span result; } span stylecolor:#0000ffreturn/span nullptr; } span stylecolor:#a31515int/span span stylecolor:#a31515findNodeNumByName/span(Node* node, span stylecolor:#a31515const/span span stylecolor:#a31515char/span* name) { span stylecolor:#008000//std::cout name : (void*)name std::endl;/span span stylecolor:#0000ffif/span (span stylecolor:#0000ffstrcmp/span(node-GetName().c_str(), name) span stylecolor:#8800000/span) span stylecolor:#0000ffreturn/span node-num; span stylecolor:#0000fffor/span (span stylecolor:#0000ffauto/span* n : node-GetChildNodes()) { span stylecolor:#a31515int/span result findNodeNumByName(n, name); span stylecolor:#0000ffif/span (result ! span stylecolor:#880000-1/span) span stylecolor:#0000ffreturn/span result; } span stylecolor:#0000ffreturn/span span stylecolor:#880000-1/span; } span stylecolor:#a31515int/span span stylecolor:#a31515main/span() { initializeNodes(); span stylecolor:#0000ffstd/span::span stylecolor:#0000ffcout/span span stylecolor:#a31515Please input number you want to find:/span span stylecolor:#0000ffstd/span::span stylecolor:#0000ffendl/span; span stylecolor:#a31515int/span n; span stylecolor:#0000ffwhile/span (span stylecolor:#0000ffstd/span::span stylecolor:#0000ffcin/span n) { span stylecolor:#0000ffif/span (nspan stylecolor:#8800000/span||nspan stylecolor:#8800007/span) span stylecolor:#0000ffbreak/span; span stylecolor:#a31515const/span span stylecolor:#a31515char/span* name findNodeNameByNum(A, n); span stylecolor:#0000ffstd/span::span stylecolor:#0000ffcout/span span stylecolor:#a31515find: /span findNodeNumByName(A, name) span stylecolor:#0000ffstd/span::span stylecolor:#0000ffendl/span; } span stylecolor:#0000ffreturn/span span stylecolor:#8800000/span; } /code/span/span输出结果分析看结果发现0137正确2456错误并都返回了3. 单单看findNodeNumByName方法基本没有问题传入的name为const char* 理论上不应该在方法中被修改。程序中的bug也不难发现这个const char*来源于findNodeNameByNum而这个指针为悬空指针所以传入findNodeNumByName中的值应为空为什么还会有值返回将node类成员函数GetName()返回值改为DebugString而DebugString继承std::string区别只是构造/析构时候返回内部成员c_str的地址。span stylecolor:#333333span stylebackground-color:#ffffffcode classlanguage-c language-cspan stylecolor:#0000ffstruct/span span stylecolor:#a31515DebugString/span : public span stylecolor:#0000ffstd/span::span stylecolor:#0000ffstring/span { DebugString(span stylecolor:#a31515const/span span stylecolor:#a31515char/span* s) : span stylecolor:#0000ffstd/span::span stylecolor:#0000ffstring/span(s) { span stylecolor:#0000ffstd/span::span stylecolor:#0000ffcout/span span stylecolor:#a31515Constructed: /span c_str() span stylecolor:#a31515:/span (span stylecolor:#a31515void/span*)c_str() span stylecolor:#a31515\n/span; } ~DebugString() { span stylecolor:#0000ffstd/span::span stylecolor:#0000ffcout/span span stylecolor:#a31515Destroyed: /span c_str() span stylecolor:#a31515\n/span; } }; span stylecolor:#0000ffclass/span span stylecolor:#a31515Node/span { ..... DebugString span stylecolor:#a31515GetName/span() {span stylecolor:#0000ffreturn/span name;} ..... } /code/span/span以0为例发现第一次findNodeNameByNum找到A节点名字的临时指针为FA50然后析构后为空传入findNodeNumByName函数中首先对A节点查找name并再次在FA50地址中赋值所以判断为相等返回相应的值。再以6为例发现, D/E/G 构造的地址都相同都为FAC0B,C构造的地址相同,都为FB70;所以当传入的是6为G的地址在第二次循环的时候,D/E/G还在原来的地址上构造导致先返回D的地址为3.同理传入的是BC的值先返回的都是B的值如下图所示