自定义ft_split函数1字节内存泄漏问题排查求助
修复ft_split的1字节内存泄漏问题
泄漏根源分析
你遇到的1字节泄漏,核心原因是代码在处理字符串末尾时,错误地分配了一个仅存'\0'的空字符串内存块。典型场景就是ft_split("hello!zzzzzzzz", 'z'):原字符串有效内容后紧跟全部分隔符,代码遍历到末尾时,未判断是否有有效字符需要复制,直接调用ft_copy分配了1字节内存,甚至可能出现数组越界写入,导致这块内存无法被正常释放。
常见错误代码示例
假设你的ft_split实现类似以下结构(这是很多初学者的典型写法):
#include <stdlib.h> static int count_words(char const *s, char c) { int count; int in_word; count = 0; in_word = 0; while (*s) { if (*s != c && !in_word) { in_word = 1; count++; } else if (*s == c) in_word = 0; s++; } return (count); } static char *ft_copy(char const *s, int start, int end) { char *word; int i; word = malloc((end - start + 1) * sizeof(char)); if (!word) return (NULL); i = 0; while (start < end) word[i++] = s[start++]; word[i] = '\0'; return (word); } char **ft_split(char const *s, char c) { char **res; int i; int start; int word_idx; if (!s) return (NULL); res = malloc((count_words(s, c) + 1) * sizeof(char *)); if (!res) return (NULL); i = 0; start = 0; word_idx = 0; while (s[i]) { if (s[i] == c) { if (i > start) res[word_idx++] = ft_copy(s, start, i); start = i + 1; } i++; } // 错误点:无判断直接调用ft_copy,会分配空字符串 res[word_idx++] = ft_copy(s, start, i); res[word_idx] = NULL; return (res); }
修复方案
1. 修复末尾空字符串分配问题
在最后调用ft_copy前,增加start < i的判断,仅当存在有效字符时才执行复制:
// 替换原来的无判断调用 if (start < i) res[word_idx++] = ft_copy(s, start, i); res[word_idx] = NULL; return (res);
2. 增加 malloc 失败的回滚处理
如果ft_copy分配内存失败,需要释放已经分配的所有单词和结果数组,避免泄漏。修改循环内的复制逻辑:
if (s[i] == c) { if (i > start) { res[word_idx] = ft_copy(s, start, i); if (!res[word_idx]) { // 释放已分配的所有单词 while (word_idx > 0) free(res[--word_idx]); free(res); return (NULL); } word_idx++; } start = i + 1; }
同时,末尾的复制也要增加失败处理:
if (start < i) { res[word_idx] = ft_copy(s, start, i); if (!res[word_idx]) { while (word_idx > 0) free(res[--word_idx]); free(res); return (NULL); } word_idx++; }
验证修复
修复后,测试ft_split("hello!zzzzzzzz", 'z')会正确返回["hello!", NULL],不会额外分配空字符串的内存块,彻底解决1字节泄漏问题。同时,malloc失败的场景也能正确释放所有已分配内存,避免其他潜在泄漏。
内容的提问来源于stack exchange,提问作者Ro ro
相关产品推荐
相关产品推荐

