Мне нужно перекодировать реализацию функции getline()
, но используя файловый дескриптор файла, а не FILE *
. Мне разрешено использовать только malloc()
и free()
, а также 5 функций, максимум 25 строк длиной. Я думаю, что я сделал правильно проект, хотя я новичок в C, и мой код, вероятно, не хорош.Кодирование getline() implentation - ошибки Valgrind
Когда я запускаю его, он работает нормально, но valgrind показывает, что я definetely lost x bytes
, x в зависимости от длины файла и READ_SIZE (макрос, определенный в заголовке).
Согласно --leak-check=full
valgrind, у меня есть утечка памяти в функции str_realloc_cat
, когда я malloc dest
. Я пытался, но не мог найти, где я должен освободить/сделать что-то еще?
Здесь ниже мой код:
char *get_next_line(const int fd)
{
static char *remaining = "";
char *buffer;
ssize_t cread;
size_t i;
i = 0;
if (remaining == NULL)
return (NULL);
if ((buffer = malloc(SOF(char) * READ_SIZE + 1)) == NULL ||
(cread = read(fd, buffer, READ_SIZE)) < 0)
return (NULL);
buffer[cread] = 0;
remaining = str_realloc_cat(remaining, buffer);
while (remaining[i])
{
if (remaining[i] == 10)
{
remaining[i] = 0;
buffer = str_create_cpy(remaining);
remaining = remaining + i + 1;
return (buffer);
}
i++;
}
return (check_eof(fd, buffer, remaining, cread));
}
char *str_realloc_cat(char *rem, char *buf)
{
size_t i;
size_t dest_i;
char *dest;
i = (dest_i = 0);
if ((dest = malloc(SOF(char) * (str_len(rem) + str_len(buf) + 1))) == NULL)
return (NULL);
while (rem[i])
{
dest[dest_i] = rem[i];
dest_i++;
i++;
}
i = 0;
while (buf[i])
{
dest[dest_i] = buf[i];
dest_i++;
i++;
}
dest[dest_i] = 0;
free(buf);
return (dest);
}
char *check_eof(const int fd, char *buffer, char *remaining, ssize_t cread)
{
if (cread == 0)
return (NULL);
if (cread < READ_SIZE)
{
buffer = remaining;
remaining = NULL;
return (buffer);
}
return (get_next_line(fd));
}
char *str_create_cpy(const char *src)
{
char *dest;
size_t i;
i = 0;
if ((dest = malloc(sizeof(char) * str_len(src) + 1)) == NULL)
return (NULL);
while (src[i])
{
dest[i] = src[i];
i++;
}
dest[i] = 0;
return (dest);
}
int str_len(const char *str)
{
size_t i;
i = 0;
while (str[i])
i++;
return (i);
}
И главный functon, если вы хотите, чтобы тест:
#define SOF(x) sizeof(x) // Why in the comments
int main(int ac, char **av)
{
int fd;
char *s;
UNUSED(ac);
if (!av[1])
return 1;
fd = open(av[1], O_RDONLY);
while ((s = get_next_line(fd)))
{
printf("%s\n", s);
free(s);
}
close(fd);
}
Благодаря любую помощь или советы.
'SizeOf (Char)' всегда один, не загрязняет окружающую среду ваш код с ним. – DyZ
Использование '#define SOF (x) sizeof (x)' - не показано, но выводится - кажется, немного бессмысленным.Он экономит 3 символа набора номера за звонок, за счет путаницы. Нехороший компромисс. –
Привет, спасибо за ваши комментарии. Я знаю, что 'sizeof (char)' всегда 1, но я думал, что это была хорошая практика, поэтому вы никогда не забудете об этом, и не забывайте, что если какой-то символ имеет более 1 байт на другой системе (очень маловероятно хоть). Кроме того, SOF действительно является определением sizeof. Это уродливо, но я должен делать всего 80 символов в строке и 25 строк на каждую функцию, поэтому для меня это было любопытно, не беспокоясь о том, чтобы снова структурировать весь мой код. –