C语言动态内存实现字符串反转的内存泄漏、参数及代码优化问题
C语言字符串反转代码问题解答
你提供的原始代码如下:
#include <stdio.h> #include <stdlib.h> char* ch_reversed(const char* const str); size_t ch_length(const char* const str); int main() { char* str = "merhaba"; printf("%s", ch_reversed(str)); return 0; } char* ch_reversed(const char* const str) { if (!ch_length(str)) return NULL; char* temp = malloc(ch_length(str) + 1); size_t length = ch_length(str); for (size_t i = 0; i < length; i++) temp[i] = str[length - i - 1]; temp[length] = '\0'; return temp; } size_t ch_length(const char* const str) { size_t length = 0; while (str[length++]) {} return length - 1; }
问题1:直接传入返回值导致的内存泄漏问题
- 这种写法确实会造成内存泄漏:
ch_reversed内部malloc申请的堆内存没有对应的free调用,虽然程序退出后操作系统会回收这部分内存,但属于不符合规范的内存泄漏写法,工程代码中不推荐。 - 要保留直接传参的写法,推荐用封装方案:
封装一层专用调用函数,内部完成反转、使用、释放的全流程,示例如下:
测试场景下也可以改用非标准的栈内存分配函数void print_reversed(const char* str) { char* reversed = ch_reversed(str); if (reversed) { printf("%s", reversed); free(reversed); } } // 调用时直接写print_reversed(str)即可,不需要额外定义变量接收反转结果alloca替换malloc,不需要手动释放,但注意栈空间有限,长字符串会触发栈溢出,不适合生产环境。
问题2:const char* const形参的合理性
- 这种写法是合适的,属于更严谨的约束:
左侧的const char保证了函数内部不会修改传入字符串的内容,符合你不会修改源串的需求,对调用方也更友好,明确传入的参数不会被篡改。
右侧的const保证了函数内部不会修改指针本身的指向(比如不会出现str = other_str这类赋值操作),是函数内部实现层面的安全约束。 - 如果不需要限制内部指针的修改,写成
const char*也完全符合要求,对外部调用者来说两种写法没有区别。
问题3:代码其他不规范/可优化点
- 重复调用
ch_length浪费性能:现在同一个字符串要遍历3次(判空、计算malloc长度、赋值给length),建议进入ch_reversed后先计算一次长度缓存下来,避免重复遍历。 - 没有对
malloc返回值做判空:malloc申请失败时会返回NULL,直接对temp指针赋值会触发段错误,必须加空指针判断,失败时返回错误或者抛出提示。 main函数中字符串字面量的指针声明缺少const:"merhaba"是存储在只读区的字符串字面量,应该声明为const char* str = "merhaba",避免误修改触发未定义行为。- 空指针、空字符串处理不完善:传入
NULL时ch_length直接访问str[length]会触发段错误;传入空字符串时直接返回NULL,会导致上层需要同时处理NULL和空字符串两种情况,建议统一返回合法的空字符串(申请1字节写入\0)。 - 没必要手动实现
ch_length:标准库string.h中的strlen是官方实现,做过底层优化,性能和稳定性都优于手动实现的版本,除非是学习目的,否则优先用标准库函数。
内容的提问来源于stack exchange,提问作者Ertuğrul Faruk Pişkin
相关产品推荐
相关产品推荐

