You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:17:23