不能直接用 char* 修改字符串字面量,因其存储在只读内存段,写操作会触发段错误;必须使用可修改内存,如字符数组、new 分配或 std::string.data()。

为什么不能直接用 char* 指针修改字符串字面量
直接对字符串字面量(如 "hello")取地址并试图逆序,程序会在运行时崩溃。因为 "hello" 存在只读内存段,char* p = "hello"; 中的 p 指向的是不可写区域,任何通过 *p = 'x' 类型的赋值都会触发段错误(Segmentation fault)。
必须确保指针指向**可修改的内存**,常见做法是:
- 用字符数组初始化:
char s[] = "hello"; char* p = s; - 用
new动态分配:char* p = new char[6]{ 'h','e','l','l','o','\0' }; - 用
std::vector<char></char>或std::string+&s[0](C++11 起保证连续存储)
双指针原地逆序的正确写法
核心逻辑是:用两个指针分别指向首尾,交换后向中间收缩。关键点在于边界判断和终止条件。
示例(安全、可执行):
void reverse(char* s) {
if (!s) return;
char* left = s;
char* right = s;
while (*right) ++right; // 找到 '\0'
--right; // 回退到最后一个有效字符
while (left <p>注意:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)"><img
src="https://img.php.cn/upload/manual/000/000/001/5d6de31fedca2993.png" alt="C函数速查手册(CHM版)" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)" class="overflowclass">C函数速查手册(CHM版)</a>
<p class="overflowclass">C函数速查手册(CHM版)</p>
</div>
<a rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 必须先定位
right到末尾字符,不能假设长度已知;strlen()也可用,但本质一样 - 循环条件是
left ,不是 <code>left ——否则奇数长度时中间字符会被换两次,等于没变 - 空字符串或单字符时,
while循环不进入,天然安全
用 std::string 配合指针操作的陷阱
std::string 对象本身不能直接用 char* 指针长期持有其内部数据,因为可能因扩容导致内存重分配,原有指针失效。
如果非要混合使用,必须满足:
- 调用
s.data()或&s[0]前,确认s不会后续被修改(如push_back、+=) - 若需动态调整容量,先
s.reserve(n)预留足够空间 - 更稳妥的做法是:逆序逻辑写成独立函数,传入
std::string&,内部用s[i]下标访问,避免裸指针
例如错误写法:std::string s = "abc"; char* p = &s[0]; s += "de"; /* 此时 p 指向已释放内存 */
性能与兼容性提醒:别忽略 const 和空终止符
如果你封装逆序函数供他人调用,接口设计直接影响安全性:
- 输入参数不该声明为
const char*——那意味着你承诺不修改它,但逆序必然要改 - 必须要求输入是以
'\0'结尾的 C 风格字符串;传入无结束符的字符块(如从二进制读取的 raw buffer)会导致while(*right)越界 - 若处理非 ASCII 字符(UTF-8),按字节逆序会破坏编码——这不是指针问题,而是语义问题,需额外判断多字节序列边界
真正容易被忽略的,是“谁负责分配、谁负责释放”这个所有权问题。用 new 分配的指针,逆序后若忘记 delete[],就是内存泄漏;而栈上数组(char s[])根本不能 delete。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










