如何在C++中通过参数为std::string指针的void函数修改字符串值?
问题分析与解决方案
我一眼就看出你代码里的问题啦——你的changeToBanana函数其实根本没修改到主函数里的字符串,原因有两个:
- 指针参数是值传递的副本:你传入的
strPtr是一个指针,但函数参数s是它的副本。当你执行s = &strVal;时,只是把这个副本的指向改成了局部变量strVal,主函数里的strPtr完全没被影响,还是指向原来的strInit。 - 局部变量的生命周期问题:就算你能让主函数的指针指向
strVal,strVal是函数内部的局部变量,函数执行结束后它就会被销毁,后续访问这个指针会触发未定义行为,非常危险。
你说用for循环逐个赋值没成功,大概率是循环时没操作指针指向的对象——比如你可能写了s[i]而不是(*s)[i],或者没先调整目标字符串的长度。不过其实根本不用这么麻烦,直接修改指针指向的字符串对象就行。
修正后的代码
因为你要求函数必须是void类型,参数必须是std::string*,那我们直接修改指针指向的对象内容,而不是修改指针本身:
#include <iostream> void changeToBanana(std::string *s) { // 直接给指针指向的字符串赋值,会自动处理内存和长度 *s = "banana"; // 也可以用string的assign成员函数,效果一样: // s->assign("banana"); } int main() { std::cout << "Hello, World!" << std::endl; std::string strInit = "apple"; std::string* strPtr; strPtr = &strInit; changeToBanana(strPtr); std::cout << *strPtr << std::endl; // 现在会输出banana啦 return 0; }
关键说明
*s表示指针s指向的std::string对象,直接给它赋值,就会修改原字符串的内容,主函数里的strInit(也就是strPtr指向的对象)就会变成"banana"。- 如果你非要用循环逐个字符赋值,得先确保目标字符串的长度足够,比如先执行
(*s).resize(strGet.size()),然后再循环赋值每个字符:void changeToBanana(std::string *s) { std::string strGet = "banana"; s->resize(strGet.size()); // 先调整目标字符串的长度 for (size_t i = 0; i < strGet.size(); ++i) { (*s)[i] = strGet[i]; } }
不过显然直接赋值更简洁高效,没必要多此一举。
内容的提问来源于stack exchange,提问作者jye
相关产品推荐
相关产品推荐

