в main
while(1){
strcpy(arr[i],read());
if (arr[i]=NULL) break;
вы никогда не выходите из цикла, потому что arr[i]=NULL
не имеет оснований быть истинным из read (из-за ошибкив read ), поэтому вы пишете из arr с неопределенным поведением (ваш сбой)
Вы плохо управляете концом файла при чтении:
fgets(line,80,stdin);
if (line != NULL) {
вам нужно проверить результат fgets нет, если строка равна NULL, за исключением проверки malloc success
notчто line[strlen(line)-1] = '\0';
бесполезно, потому что fgets ставит последний нулевой символ, к счастью, как может работать strlen ?
Так что read может быть:
char *read(){
char *line = (char *) malloc (80 * sizeof(char));
if (line != NULL) {
if (fgets(line,80,stdin) == NULL) {
free(line);
return NULL;
}
}
return line;
}
Поскольку read может возвращать NULL, вам необходимо изменить
strcpy(arr[i],read());
, а также почему вы предварительно выделяете строки, а также выделяете в read?в настоящее время вы теряете память, выделяемую каждый раз при чтении
Кажется, лучше заменить цикл на
while((arr[i] == read()) != NULL)
//printf("%s", arr[i]); //DEBUG
i += 1;
}
и удалить предраспределения строк
Другая проблемаэто когда файл содержит более 100 строк (или, может быть, некоторые строки обрезаются слишком долго), в этом случае вы записываете из arr .На самом деле вам не нужно сохранять столько строк, вам просто нужно сохранить максимум 10 строк
Предложение:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *read() {
char line[80];
if (fgets(line, 80, stdin) == NULL)
return NULL;
return strdup(line);
}
int main()
{
char * arr[10] = { NULL };
char * p;
int i = 0, n = 0;
while((p = read()) != NULL) {
n += 1;
free(arr[i]);
arr[i] = p;
if (++i == 10)
i = 0;
}
/* get older line index and line count to print */
if (n <= 10)
i = 0;
else
n = 10;
while (n-- != 0) {
puts(arr[i]);
free(arr[i]);
if (++i == 10)
i = 0;
}
return 0;
}
Compilation and execution :
pi@raspberrypi:/tmp/d $ gcc -g -pedantic -Wextra q.c
pi@raspberrypi:/tmp/d $ ./a.out < q.c
n = 10;
while (n-- != 0) {
puts(arr[i]);
if (++i == 10)
i = 0;
}
return 0;
}
Примечание. Я не удалил \ nстроки чтения и я использую ставит , поэтому печатаются пустые строки, в то время как строка чтения не обрезается из-за слишком длинной
Если файл короче, чем 10 строк:
pi@raspberrypi:/tmp/d $ tail -n 5 q.c | ./a.out
i = 0;
}
return 0;
}
Под valgrind :
pi@raspberrypi:/tmp/d $ valgrind ./a.out < q.c
==18496== Memcheck, a memory error detector
==18496== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==18496== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==18496== Command: ./a.out
==18496==
while (n-- != 0) {
puts(arr[i]);
free(arr[i]);
if (++i == 10)
i = 0;
}
return 0;
}
==18496==
==18496== HEAP SUMMARY:
==18496== in use at exit: 0 bytes in 0 blocks
==18496== total heap usage: 43 allocs, 43 frees, 5,699 bytes allocated
==18496==
==18496== All heap blocks were freed -- no leaks are possible
==18496==
==18496== For counts of detected and suppressed errors, rerun with: -v
==18496== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)