反转C风格字符串时长度异常增加的技术咨询
反转C风格字符串的问题排查与解决
嘿,我看到你在啃《The C Programming Language》的时候遇到反转C风格字符串的问题了,咱们一步步来捋清楚~
首先得给你点个赞:你对C风格字符串的理解完全没毛病——像"voldemort"这种字面量确实是一个10字节的字符数组(9个有效字符加末尾的\0终止符),这个核心概念抓得特别准!
你提到反转时出现了字符串长度增加的问题,大概率是在处理\0终止符或者数组内存分配的时候踩了坑。咱们先拆解正确的反转逻辑,再看看可能哪里出了问题:
两种常见的反转思路及注意点
1. 原地反转(高效,无需额外数组)
这种方法不需要新建数组,直接在原字符串上交换字符,是最常用的方式:
- 核心逻辑:用两个指针,一个指向字符串开头,一个指向最后一个有效字符(注意不是
\0),然后交换两个指针指向的字符,直到指针相遇或交错。 - 关键注意事项:必须使用可修改的字符数组,不能用
char *str = "voldemort"这种指向只读字面量的指针——因为字符串字面量存储在只读内存区,修改它会触发未定义行为。
代码示例:
#include <stdio.h> #include <string.h> void reverse_string(char *str) { if (str == NULL) return; // 提前处理空指针情况 char *start = str; char *end = str + strlen(str) - 1; // 指向最后一个有效字符,跳过\0 char temp; while (start < end) { // 交换两个字符 temp = *start; *start = *end; *end = temp; // 移动指针 start++; end--; } } int main() { char str[] = "voldemort"; // 用可修改的字符数组存储字符串 reverse_string(str); printf("%s\n", str); // 输出: tromedlov return 0; }
2. 新建数组存储反转结果(你的初始思路)
你的思路本身是对的,但容易在数组大小和\0处理上出错:
- 核心注意点:新数组的大小必须是
strlen(原字符串) + 1——因为strlen()返回的是不含\0的有效字符数,必须多留一个字节给终止符。 - 你遇到的“长度增加”问题,很大概率是因为数组大小只分配了
strlen()的长度,导致\0无处可放,程序会越界读取内存中后续的随机数据,直到找到下一个\0,看起来就像是字符串变长了。
代码示例:
#include <stdio.h> #include <string.h> #include <stdlib.h> char* reverse_string_new(const char *str) { if (str == NULL) return NULL; int len = strlen(str); // 分配len+1个字节,预留\0的位置 char *reversed = (char *)malloc(len + 1); if (reversed == NULL) return NULL; // 检查内存分配是否成功 // 逐个字符反转赋值 for (int i = 0; i < len; i++) { reversed[i] = str[len - 1 - i]; } reversed[len] = '\0'; // 手动添加终止符,这步绝对不能忘! return reversed; } int main() { const char *original = "voldemort"; char *reversed = reverse_string_new(original); if (reversed != NULL) { printf("%s\n", reversed); // 输出: tromedlov free(reversed); // 记得释放动态分配的内存,避免泄漏 } return 0; }
总结你可能踩的坑
你说的“字符串长度增加”,几乎可以肯定是以下情况之一:
- 新建数组时只分配了
strlen()的长度,没有给\0留位置,导致越界访问内存,读取到了额外的随机数据; - 使用了只读的字符串字面量指针进行修改,触发了未定义行为,导致内存数据混乱。
按照上面的代码调整一下,应该就能解决问题啦!
内容的提问来源于stack exchange,提问作者David Stevens
相关产品推荐
相关产品推荐

