“目前有这个代码。它遵循一套必要的具体准则;因此,没有while循环或其他不是我们自己在头文件中创建的函数。
我写了一个函数,它将拆分一个字符串。只有外部函数。允许的是malloc和free。基本上,它分配(使用malloc(3))并返回一个字符串数组,该数组是通过使用字符'c'作为分隔符拆分's'获得的。数组必须以NULL指针结束。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include "libft.h"
static int ft_length(char const *s, char c)
{
size_t i;
size_t words;
i = 0;
words = 0;
while (s[i])
{
while (s[i] == c)
{
i++;
}
if (s[i] != c && s[i] != '\0')
{
words++;
}
while (s[i] != c && s[i] != '\0')
{
i++;
}
}
return (words);
}
char *ft_copy(char *s, char c)
{
int i;
char *cpy;
i = 0;
while (*s && *s == c)
s++;
while (s[i] && s[i] != c)
i++;
cpy = malloc(sizeof(char) * i + 1);
if (cpy == NULL)
return (NULL);
i = 0;
while (s[i] && s[i] != c)
{
cpy[i] = s[i];
i++;
}
cpy[i] = '\0';
return (cpy);
}
static void *cleanup(char **cpy, int j)
{
int i = 0;
while (i < j)
{
free(cpy[i]);
i++;
}
return (0);
}
char **ft_split(char const *s, char c)
{
size_t i;
char **cpy;
size_t count;
size_t j;
i = 0;
j = 0;
if (!s && !c)
return (NULL);
count = ft_length(s, c);
cpy = malloc(sizeof(char *) *(count + 1));
if (!cpy)
return (NULL);
while (s[i])
{
while (s[i] == c)
i++;
if ((int)i == ft_strlen((char *)s) && j == 0)
{
cpy[0] = 0;
return (cpy);
}
if (s[i] != c)
{
cpy[j] = ft_copy((char *)&(s[i]), c);
if (cpy[j] == NULL)
{
cleanup(cpy, j);
return (NULL);
}
j++;
}
while (s[i] != c && s[i] != '\0')
i++;
}
cpy[count] = NULL;
return (cpy);
}
然而,当运行测试仪时,大约1字节的内存没有被正确释放,如以下行所示:
Error in test 3: ft_split("hello!zzzzzzzz", 122:'z'):
Memory leak: 0x55ae6a0998f0 - 1 bytes
You failed to free the memory allocated at:
ft_copy's malloc allocaton:
Error in test 4: ft_split("\\t\\t\\t\\thello!\\t\\t\\t\\t", 9:'\\t'):
Memory leak: 0x55ae6a09a920 - 1 bytes
You failed to free the memory allocated at:
ft_copy's malloc allocaton:
Error in test 7: ft_split("^^^1^^2a,^^^^3^^^^--h^^^^", 94:'^'):
Memory leak: 0x55ae6a09aa00 - 1 bytes
You failed to free the memory allocated at:
ft_copy's malloc allocaton:
想知道是否需要对代码进行全新的重写?然而,我似乎非常接近,只是不知道这个单一的字节,我不能释放是来自。
我希望所有的记忆都能被释放。
1条答案
按热度按时间rjee0c151#
cleanup()
应该释放cpy
。cleanup()
需要一个计数j
,但在正常情况下,你没有计数,所以删除参数,并依赖NULL
。ft_strlen()
缺失,因此消除了它。你调用ft_strlen()
的外部循环的每一次迭代,以确定我们是否在字符串的末尾。您只需检查s[i] == '\0'
或!s[i]
即可。1.最小化变量的作用域。
1.首选初始化变量。
1.在遍历数组时,优先使用
for()
而不是while()
。1.(不固定)不要为不同的事情重复使用变量。这可能是或可能不是依赖性。最小化变量的作用域。
NULL
vs\0
vs0
。1.(部分修复)首选对非负变量使用无符号类型(
size_t
)。(char *)&(s[i])
很好,但s + i
是一种更直接的说法。if ((int)i == ft_strlen((char *)s) && j == 0)
意味着我们已经完成了字符串,所以只需要break以避免重复代码。if (s[i] != c)
是冗余的。你知道的,它的情况下,否则前一个循环不会终止。示例运行: