Я относительно новичок в C и malloc. Я написал lib с основными функциями, которые я наполняю новыми по ходу работы и которые я использую для других небольших проектов, подобных этому.
Я услышал о Valgrind и решил проверить с ним свою программу, но не могу понять, почему у меня так много leaks. Мне кажется, что все мои mallocs защищены с помощью if (line == NULL) при использовании функций, использующих сами malloc.
Не могли бы вы вернуть меня сюда?
static char *concator(char *s1, char *s2, size_t len)
{
char *line;
size_t size;
if (!s1 || !s2)
return (NULL);
size = strlen(s1) + strlen(s2);
line = (char*)memalloc(sizeof(char) * size + 1);
if (line == NULL)
return (NULL);
strcpy(line, s1);
strncat(line, s2, len);
strdel(&s1);
return (line);
}
int line_reader(const int fd, char **line)
{
static char buf[BUFF_SIZE];
char *pos;
int ret;
if (fd < 0 || !line || read(fd, buf, 0) < 0 || BUFF_SIZE < 1)
return (-1);
*line = strnew(0);
if (line == NULL)
return (-1);
while (1)
{
pos = strchr(buf, '\n');
if (pos)
{
*line = concator(*line, buf, pos - buf);
if (line == NULL)
return (-1);
strncpy(buf, &buf[pos - buf + 1], BUFF_SIZE - (pos - buf));
return (1);
}
*line = concator(*line, buf, BUFF_SIZE);
if (line == NULL)
return (-1);
ret = read(fd, buf, BUFF_SIZE);
buf[ret] = '\0';
if (!ret)
return ((**line) ? 1 : 0);
}
}
Valgrind, вероятно, сообщает вам (включите его отчет здесь), что вы не освобождаете выделенную память до завершения программы.
@ChrisTurner Как мне получить free, что мне нужно для return?
Вы освободите его после того, как закончите пользоваться им, а не когда вернете.
вы не используете realloc для увеличения размера *line - вы продолжаете выделять для него новые блоки памяти и теряете старые.
Я почти уверен, что strncpy(buf, &buf[pos - buf + 1], BUFF_SIZE - (pos - buf)); - это UB (перекрывающиеся исходные / целевые буферы).
@melpomene Как я могу быть уверен?
@RobertHarvey Не могли бы вы мне подсказать, где это будет расположено в моем коде?
После возвращения. Вы сами сказали: вы не сможете вернуть его, если сначала освободите.
@RobertHarvey Я думал, что ничего не было сделано после return.
Ну, вы делаете что-то с возвращенным значением, не так ли? Иначе какой смысл его возвращать?
@RobertHarvey Абсолютно да
В ПОРЯДКЕ. Итак, когда вы закончите с этим, free это.
Похоже, путаница связана с тем, когда вы освободите его. Этого точно не будет, пока вы не вернете переменную. Это может быть какая-то другая функция, которая использует эту переменную. Когда вы размещаете данные внутри функции и возвращаете их, ответственность за освобождение данных ложится на того, кто вызвал эту функцию.
@Wizzardzz Я не знаю, это твой код. Части источника / цели перекрываются или нет?
Примечание: || BUFF_SIZE < 1 не имеет никакого смысла после read(fd, buf, 0).





Бесплатно line после того, как вы его используете, например:
char* line;
int rc = line_reader(fd, &line);
if (rc > 0)
{
//use line
printf("%s\n", line);
//then free it
free(line);
}
Это должно исправить проблемы с утечкой памяти, о которых сообщает valgrind. Однако следите за другими ошибками, упомянутыми в комментариях.
Где в вашем коде вы
freeразмещаете выделенную память?