Что вызывает Ошибку сегментирования и как это исправить?
#include <stdio.h>
#include <math.h>
unsigned int fact(int n){
unsigned int res = 1;
for (int i = 2;i <= n; i++){
res *= i;
}
return res;
}
double absolute(double i){
if (i < 0){return -i;} else {return i;}
}
void main(void){
double acc,curr,diff;
int n = 1;
printf("Input accuracy: ");
do{
scanf("%lf\n",acc);
} while (acc <= 0);
diff = 155;
while(absolute(diff) >= acc){
diff = pow(2,n)/fact(n);
curr += diff;
n += 1;
}
printf("%lf with %d members\n",&curr,&n);
}
Что-то в этом коде вызывает ошибку сегментирования. Дословно "Ошибка сегментирования (образ памяти сброшен на диск)". Найденные мной ответы объясняли, что проблема заключается в попытке обратиться к разделу памяти, к которому нету доступа (как например при попытке получить n-ый элемент в массиве длиной n). Однако у меня никаких обращений к памяти кроме scanf и printf нету. Cижу в VS code с установленным gcc на Fedora Linux 40.
Ответы (1 шт):
Начнем с того, что в scanf
указывается адрес, куда надо записать значение, а в printf
— напротив, значение, которое надо вывести. Это к конкретному вашему вопросу. Сейчас у вас попытка записать введенное значение по адресу, в который преобразуется (кстати, неопределенное) значение acc
, приводит к обращению, как вы верно написали,
к разделу памяти, к которому нету доступа
Кстати, компилятор должен был неоднократно предупредить вас о неприятностях... Предупреждал?
Далее, судя по коду, вы считаете
Если, конечно, не ошиблись и считать надо не от n == 0
. Но при этом для достижения большой точности могут потребоваться большие факториалы, которые вызовут переполнение. Все члены ряда положительные, так что искать значение по модулю не надо, тем более писать свою функцию, а не пользоваться стандартной fabs
. Считать каждый очередной член проще из предыдущего.
Словом, если категорически нельзя писать просто и точно :)
int main() { printf("%lf\n",exp(2)-1); }
(кстати, функция main
обязана возвращать int
, а не void
!), то я бы написал примерно так:
#include <stdio.h>
#include <math.h>
int main()
{
double acc, sum = 0, term = 1;
int n = 0;
do // Заметим, что это защита ТОЛЬКО от ввода отрицательного числа,
{ // но не, например, строки символов, словом, не-числа.
printf("Input accuracy (>0): ");
scanf("%lf",&acc);
} while (acc <= 0);
while(term >= acc)
{
sum += term *= 2./++n;
printf("term = %lf sum = %lf\n", term,sum);
}
printf("%lf with %d members\n",sum,n);
}
Кстати, в этом коде вы видите правильное использование scanf
и printf
.