程序改错---字符串
请说明以下函数的目的 且找出其中的所有错误
int test_func(char* src) {int len = strlen(src);char* dest = (char*)malloc(len);if(!dest) return -1;const char* d = dest; const char* s = src[len];while(len-- != 0) {d++ = s--;} printf("%s", dest);return 0;
}
函数目的
这个函数试图实现字符串的逆序复制和打印,但存在严重错误。其理想行为是:
- 获取输入字符串长度
- 分配新内存空间
- 将源字符串从后向前复制到新空间(实现逆序)
- 打印逆序后的字符串
- 返回操作状态
错误列表(共7个关键错误)
1. 内存分配不足
char* dest = (char*)malloc(len);
- 错误:未为字符串终止符
\0
分配空间 - 后果:导致后续操作越界访问
- 修正:
char* dest = (char*)malloc(len + 1); // +1 for null terminator
2. 指针类型错误
const char* d = dest;
- 错误:
const
修饰符使d
成为只读指针- 无法通过
d
修改目标内存
- 后果:后续
d++ = ...
操作会导致编译错误 - 修正:
char* d = dest; // 移除const
3. 错误的指针初始化
const char* s = src[len]; // 严重错误!
- 错误:
src[len]
是字符(\0
),不是指针- 尝试将字符值赋给指针变量
- 后果:
s
指向无效内存地址(地址值为0) - 修正:
const char* s = src + len - 1; // 指向最后一个有效字符
4. 无效的赋值操作
d++ = s--;
- 错误:
d++
不是有效的左值(不能作为赋值目标)- 未使用解引用操作符
*
- 对指针
s
直接递减而非内容
- 后果:编译失败,逻辑错误
- 修正:
*d++ = *s--; // 正确解引用和赋值
5. 缺少字符串终止符
// 循环后未添加\0
- 错误:未在复制完成后添加终止符
- 后果:
printf
可能越界读取,导致崩溃或乱码 - 修正:
*d = '\0'; // 在循环后添加
6. 内存泄漏
// 分配内存后未释放
- 错误:未调用
free(dest)
- 后果:每次调用泄露len+1字节内存
- 修正:
printf("%s", dest); free(dest); // 添加释放
7. 空指针风险
int len = strlen(src); // src可能为NULL
- 错误:未检查输入指针有效性
- 后果:如果
src
为NULL,strlen
会导致崩溃 - 修正:
if(!src) return -1; // 添加NULL检查
完整修正代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int test_func(char* src) {// 1. 检查输入有效性if(!src) return -1;// 2. 获取长度并检查空字符串int len = strlen(src);if(len == 0) {printf("(empty)\n");return 0;}// 3. 分配足够空间(含终止符)char* dest = (char*)malloc(len + 1);if(!dest) return -1;// 4. 设置指针char* d = dest; // 可修改的目标指针const char* s = src + len - 1; // 指向源字符串最后一个字符// 5. 逆序复制while(len-- > 0) {*d++ = *s--; // 正确解引用和赋值}*d = '\0'; // 添加终止符// 6. 输出并释放内存printf("%s", dest);free(dest);return 0;
}
修正说明
-
安全增强:
- 添加NULL指针检查
- 处理空字符串特殊情况
-
内存管理:
- 正确分配len+1空间
- 确保释放分配的内存
-
指针操作:
- 使用
char* d
代替const char* d
- 正确初始化源指针
src + len - 1
- 使用解引用操作
*d
和*s
- 使用
-
字符串完整性:
- 循环后添加终止符
\0
- 循环后添加终止符
-
边界处理:
- 循环条件
len-- > 0
避免负值 - 空字符串单独处理
- 循环条件
测试用例
int main() {test_func("hello"); // 输出: ollehtest_func(""); // 输出: (empty)test_func(NULL); // 返回: -1test_func("a"); // 输出: areturn 0;
}
关键改进点
原错误 | 修正方案 | 重要性 |
---|---|---|
malloc(len) | malloc(len+1) | 致命 |
const char* d | char* d | 高 |
src[len] | src + len - 1 | 致命 |
d++ = s-- | *d++ = *s-- | 高 |
无终止符 | *d = '\0' | 高 |
无释放 | free(dest) | 中 |
无NULL检查 | if(!src) | 高 |
修正后的函数能安全实现字符串逆序功能,正确处理边界情况,且无内存泄漏风险。