double *tab;
tab = malloc(1*sizeof(*tab));
temp = realloc(*tab, i*sizeof(**tab));
Они выделяют место для указателей, но вы храните двойные, которые обычно больше. Так что вам нужно ...
tab = malloc(1*sizeof(*tab));
temp = realloc(*tab, i * sizeof(double));
**(tab + i - 2) = A;
**(tab + i - 1) = B;
Это тоже не совсем верно. Это добавление к адресу tab
, который указывает на указатель, а затем попытка stick 2 удваивается там, где есть только место для одного указателя.
Вместо этого вы хотите добавить к *tab
адрес выделенной памяти и разыменовать его.
*(*tab + i - 2) = A;
*(*tab + i - 1) = B;
Использование *tab
в качестве массива делает то же самое и намного проще для чтения.
(*tab)[i - 2] = A;
(*tab)[i - 1] = B;
while (fscanf(file, "%lf;%lf\n", &A, &B) != EOF)
Это тоже не совсем верно. Если он всегда видит правильный ввод, это нормально. Но если он видит что-то, он не ожидает, что повиснет. fscanf
не будет перемещать курсор, если его синтаксический анализ не удался. Он будет многократно читать одну и ту же плохую строку снова и снова. И какой бы мусор ни был в A
, а B
попадет в tab
. Это одна из многих проблем с scanf
и fscanf
.
Вместо этого отделяйте чтение от анализа строки, используя fgets
и sscanf
. Это позволяет избежать ненужных данных и улучшить обработку некорректных строк.
char line[BUFSIZ];
while (fgets(line, sizeof(line), file) != NULL)
{
if( sscanf(line, "%lf;%lf\n", &A, &B) != 2 ) {
fprintf(stderr, "%s could not be parsed\n", line);
continue;
}
...
}