Определите ошибку, вызывающую ошибку сегментации (сброс ядра)

0

Вопрос

Я новичок в программировании на си. Решил, что буду учиться, выполняя некоторые из задач, поставленных в открытом учебном пособии cs50. Следующий код выдает ошибку ошибки сегментации (сброс ядра). Я не могу понять, почему. Я читал, что ошибка сегментации связана с доступом к памяти, к которой у вас нет доступа. Я не понимаю, что могло бы быть причиной этого. Я предполагаю, что это связано с указателями. Я новичок в указателях. Спасибо.

    #include <stdio.h>

// https://cs50.harvard.edu/x/2021/labs/1/population/

float yearly_llamas(float starting_population) {
    // returns number of llamas at the end of the year
    float born = starting_population / 3;
    float died = starting_population / 4;
    float end_of_year_pop = starting_population + born - died;

    return end_of_year_pop;
}

int main(void) {
    
    // use floats for precision
    float *start_population;
    float *end_population;

    // set start lower limit
    int start_min = 9;

    
    // make sure input for starting population is greater than or equal to 9
    do {
        printf("Starting population: ");
        scanf("%f", start_population);
    } while (*start_population < start_min);
    
 

    // get ending population, make sure greater than or equal to the starting population
    do {
        printf("Ending population: ");
        scanf("%f", end_population);
    } while (*end_population < *start_population);

    // print for verification
    printf("%f\n", *start_population);
    printf("%f\n", *end_population);

    float end_pop = yearly_llamas(*start_population);

    printf("Llamas at the end of the year: %f\n", end_pop);


  return 0;
}
c cs50 pointers segmentation-fault
2021-11-24 05:03:05
3
0

Вы объявили указатель с плавающей точкой, но этот указатель просто ни на что не указывал, потому что вы не назначили ему адрес.

Измените эти строки

float *start_population;
float *end_population;

Для

float f_start_population;
float f_end_population;
float *start_population = &f_start_population;
float *end_population = &f_end_population;

следует устранить ошибку сегментации.

2021-11-24 08:35:58
0

В то время как другой ответ подсказывает вам решение, я хочу подчеркнуть способ поиска (и решения) такого рода проблем: используйте отладчик. Это важный инструмент программиста, и лучше всего научиться использовать его раньше, чем позже. В этом случае ваша проблема достаточно проста, чтобы ее можно было легко найти с помощью любого отладчика. Позже, когда вы будете работать с более сложным кодом и многопоточностью, вам будет трудно научиться его использовать, пока вы пытаетесь решить свою (сложную) проблему. Пожалуйста, попробуйте решить эту проблему самостоятельно с помощью отладчика.

Если вы работаете в Linux, вы можете использовать gdb и запускать код до тех пор, пока он не выйдет из строя. Затем вы проверяете обратный путь (bt) , чтобы увидеть последнюю выполненную строку. Наконец, вы определяете точку останова (p #n где #n является номером строки) в предыдущей строке сбоя, и вы проверяете значения (p $variable с $variable имя вашей переменной) и попытайтесь понять, почему это не работает.

С отладчиком графического интерфейса это должно быть проще (например, с Visual Studio или Code::blocks).

2021-11-24 08:58:20
0

Когда вы объявляете переменную указателя f примерно так float *f; вы можете "использовать" его только в том случае, если указатель действительно указывает на зарезервированную вами память (термин выделен). Вы можете либо выделить переменную в "куче", используя malloc() функция или, проще говоря, создайте отдельную переменную в стеке (называемую автоматической переменной), написав float my_float; и используешь это. Таким образом, вы получаете:

float my_startfloat;
float *start_population = &my_startfloat;

Тем не менее, я бы объявил только плавающую (первую) строку, а затем, при необходимости, использовал ее адрес: &my_startfloat. Например:

 float my_startfloat;
 scanf("%f", &my_startfloat);
2021-11-24 09:08:03

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................