当前位置: 首页 > news >正文

程序改错---字符串

请说明以下函数的目的 且找出其中的所有错误

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;
}

函数目的

这个函数试图实现字符串的逆序复制和打印,但存在严重错误。其理想行为是:

  1. 获取输入字符串长度
  2. 分配新内存空间
  3. 将源字符串从后向前复制到新空间(实现逆序)
  4. 打印逆序后的字符串
  5. 返回操作状态

错误列表(共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];  // 严重错误!
  • 错误
    1. src[len]是字符(\0),不是指针
    2. 尝试将字符值赋给指针变量
  • 后果s指向无效内存地址(地址值为0)
  • 修正
    const char* s = src + len - 1;  // 指向最后一个有效字符
    
4. 无效的赋值操作
d++ = s--;
  • 错误
    1. d++不是有效的左值(不能作为赋值目标)
    2. 未使用解引用操作符*
    3. 对指针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;
}

修正说明

  1. 安全增强

    • 添加NULL指针检查
    • 处理空字符串特殊情况
  2. 内存管理

    • 正确分配len+1空间
    • 确保释放分配的内存
  3. 指针操作

    • 使用char* d代替const char* d
    • 正确初始化源指针src + len - 1
    • 使用解引用操作*d*s
  4. 字符串完整性

    • 循环后添加终止符\0
  5. 边界处理

    • 循环条件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* dchar* d
src[len]src + len - 1致命
d++ = s--*d++ = *s--
无终止符*d = '\0'
无释放free(dest)
无NULL检查if(!src)

修正后的函数能安全实现字符串逆序功能,正确处理边界情况,且无内存泄漏风险。

http://www.dtcms.com/a/276766.html

相关文章:

  • 十三、K8s自定义资源Operator
  • 客户资源被挖?营销方案泄露?企业经营信息保护避坑指南
  • Python Day11
  • Agent任务规划
  • 【PMP备考】敏捷思维:驾驭不确定性的项目管理之道
  • QT中设计qss字体样式但是没有用【已解决】
  • 文件系统(精讲)
  • JVM与系统性能监控工具实战指南:从JVM到系统的全链路分析
  • 【每日刷题】阶乘后的零
  • SOEM build on ubuntu
  • Golang实战:使用 Goroutine 实现数字与字母的交叉打印
  • 使用bp爆破模块破解pikachu登录密码
  • 使用frp内网穿透:将本地服务暴露到公网
  • 张量类型转换
  • 深入探讨Java的ZGC垃圾收集器:原理、实战与优缺点
  • 格密码--数学基础--08最近向量问题(CVP)与格陪集
  • Mentor软件模块复杂,如何分角色授权最合理?
  • 【PTA数据结构 | C语言版】阶乘的递归实现
  • 串口屏的小记哦
  • 鸿蒙进程通信的坑之ServiceExtensionAbility
  • Datomic数据库简介(TBC)
  • Ntfs!LfsFlushLfcb函数分析之Ntfs!_LFCB->LbcbWorkque的背景分析3个restart页面一个普通页面的一个例子
  • 如何在IEEETrans格式的latex标题页插入图像
  • CCS-MSPM0G3507-4-基础篇-串口通讯-实现收和发
  • Java SE--抽象类和接口
  • 面试150 对称二叉树
  • Waiting for server response 和 Content Download
  • 嵌入式程序调试工具
  • 《人件》阅读笔记
  • 【Flask】基础入门