2016-02-08 4 views
-2

(Я просто уполномочен использовать: malloc, free, read)
Я пытаюсь получить следующую строку в файле с любым BUF_SIZE, но это возвращает мне неправильное значение.
Таким образом, возвращается (неправильное значение, недостающие Firsts символы) Значение:C - Получить следующую строку

3 
1 - #include <stdio.h> 
1 - dlib.h> 
1 - clude "libft/libft.h" 
1 - BUFF_SIZE 32 

Мой исходный код:

#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include "libft/libft.h" 
# define BUFF_SIZE 32 

int  get_next_line(int const fd, char **line) 
{ 
    char buffer[BUFF_SIZE + 1]; 
    size_t i; 
    size_t size; 

    if (!(*line = malloc(BUFF_SIZE))) 
     return (-1); 
    *line[0] = '\0'; 
    while (read(fd, buffer, BUFF_SIZE) > 0) 
    { 
     buffer[BUFF_SIZE + 1] = '\0'; 
     if (buffer[0] == '\n') 
      return (1); 
     if (ft_strchr(buffer, '\n') != NULL) 
     { 
      i = 0; 
      size = ft_strlen(*line); 
      buffer[BUFF_SIZE + 1] = '\0'; 
      while (buffer[i] != '\0') 
      { 
       if (buffer[i] == '\n') 
       { 
        if (!(*line = realloc(*line, i + size))) 
         return (-1); 
        buffer[i] = '\0'; 
        ft_strncat(*line, buffer, i); 
        return (1); 
       } 
       i++; 
      } 
     } 
     if (!(*line = realloc(*line, BUFF_SIZE))) 
      return (-1); 
     ft_strncat(*line, buffer, BUFF_SIZE); 
    } 
    return (0); 
} 

int  main(void) 
{ 
    int  fd; 
    int  ret; 
    char *line; 

    if ((fd = open("main.c", O_RDONLY)) < 3 && fd != 0) 
     return (-1); 
    printf("%d\n", fd); 
    ret = get_next_line(fd, &line); 
    printf("%d - %s\n", ret, line); 
    ret = get_next_line(fd, &line); 
    printf("%d - %s\n", ret, line); 
    ret = get_next_line(fd, &line); 
    printf("%d - %s\n", ret, line); 
    ret = get_next_line(fd, &line); 
    printf("%d - %s\n", ret, line); 
    return (0); 
} 
+1

', если ((буфер = таНос (BUFF_SIZE)) || (TMP = таНос (BUFF_SIZE))!!) возврата (-1);' -> возможно утечка памяти. –

+0

Это утечка первого вызова malloc, и второй вызов завершается с ошибкой. буфер не освобождается в этом случае. – Bluehorn

+0

Есть ли причина, по которой вы используете чтение, а не fread? –

ответ

0

Я получил это компилировать, заменив все функции ft_blah с их string.h эквиваленты. Есть много проблем.

Строки в C имеют нулевое завершение, поэтому для этого нужного элемента требуется дополнительный байт. Если вы хотите выделить строку одного символа, вам нужно выделить два байта.

Следующая большая проблема заключается в том, что вы продолжаете пытаться добавить к tmp, но он имеет только один байт. tmp должен иметь больше памяти, выделенной для него, когда вы идете.

На тему выделения памяти buffer никогда не возвращается, поэтому нет необходимости выделять память для нее в куче. Он может быть просто в стеке и автоматически освобожден, когда функция вернется. char buffer[2] = "".

Вы должны использовать strncat, а не strcpy, чтобы объединить строки.

Кажется ft_strverif просто копирует строку? Я не знаю, почему вы вызываете его перед вызовом strcpy, который просто скопирует строку. strcpy(tmp, ft_strverif(buffer)); означает, что buffer бесполезно копируется дважды. Хуже того, эта дополнительная копия никогда не бывает свободной, поэтому она будет утечка памяти.

Я предлагаю полностью исключить tmp и вместо этого добавить прямо к line. Используйте realloc, чтобы добавить больше памяти в line, возможно, лучше всего добавить память в куски или удвоить ее каждый раз для повышения эффективности.

Если вы эмулируете getline, обратите внимание, что getline берет длину уже выделенного буфера строк по определенной причине. Это позволяет использовать line в цикле while(getline...) без необходимости освобождать каждую итерацию цикла. Фактически line становится повторно используемым буфером.

И наконец, всегда работайте с -Wall или даже -Weverything, если ваш компилятор поддерживает его. Исправьте все предупреждения, даже если они кажутся глупыми. Затем запустите свой код с помощью valgrind, он расскажет вам, когда вы используете неинициализированную память или где вы пропускаете память. Очень, очень полезно.

Как только все это сделано, get_next_line станет намного проще.

int get_next_line(int const fd, char **line) 
{ 
    char buffer[2] = ""; 

    /* Allocate line memory if needed */ 
    if(!*line) 
     *line = malloc(100 * sizeof(char)); 

    /* Blank out the line */ 
    *line[0] = '\0'; 

    while(read(fd, buffer, 1) > 0) { 
     strncat(*line, buffer, 1); 
     if(buffer[0] == '\n') 
      break; 
    } 

    return 0; 
} 

Упражнения, оставленные для вас ...

  • Защита от перелива line.
  • Не используйте статический размер для line.
  • get_next_line grow line по необходимости.
  • Позвольте абоненту узнать, насколько велика line (например, getline).
+0

@LaJ Вы должны открыть новый вопрос. После того, как вопрос будет меняться, будет сложно следовать. – Schwern

Смежные вопросы