C++中char指针浅拷贝后修改副本无法同步改变原指针值如何解决
问题原因
你代码里的char* str = "Hello";是让指针指向了只读存储区的字符串字面量。C++中字符串字面量是const char类型,存储在进程的只读内存段,直接对这块地址做写入操作属于未定义行为:轻则写入操作被编译器优化忽略、输出保持原字符串,重则触发内存访问违规直接导致程序崩溃。你当前运行后输出"Hello"就是写入操作被忽略的表现,本身就不是合法的可预期行为。
实现方案
要实现修改str2指向的内容时str指向的内容同步变化,核心是让两个指针指向同一块可读写的内存区域,两个指针存储的地址完全一致时,对地址上内容的修改对两个指针都是可见的。
写法1:用栈上字符数组存储字符串
这是最简便的写法,适合字符串长度固定、不需要跨作用域使用的场景:
#include <iostream> int main() { // 在栈上开辟可写的字符数组,将字符串字面量的内容拷贝到数组中 char str[] = "Hello"; char* str2 = str; // str2直接指向数组首地址,和str指向同一块内存 str2[0] = 'M'; std::cout << str << std::endl; // 此处输出为Mello,如果要得到你注释里写的Mellow,需要保证内存足够的前提下插入'w'字符 return 0; }
写法2:手动分配堆内存存储字符串
适合需要长生命周期、动态调整字符串长度的场景:
#include <iostream> #include <cstring> int main() { // 开辟6字节的可写堆内存(5个字符+1个末尾结束符'\0') char* str = new char[6]; std::strcpy(str, "Hello"); char* str2 = str; str2[0] = 'M'; std::cout << str << std::endl; // 输出Mello delete[] str; // 用完必须释放堆内存,避免内存泄漏 return 0; }
关键提醒
- 不要用非const指针直接指向字符串字面量,新版本GCC、Clang、MSVC都会对这种写法直接报编译警告,强制写入会触发不可预期的错误。
- 多个指针指向同一块内存时,内存的生命周期必须长于所有指针的使用周期,否则会出现野指针访问问题。
内容的提问来源于stack exchange,提问作者Danniel Lee
相关产品推荐
相关产品推荐

