Identificar el error que causa la falla de segmentación (núcleo volcado)

Soy nuevo en la programación c. Decidí que aprendería haciendo algunos de los conjuntos de problemas en el material didáctico abierto cs50. El siguiente código produce un error de falla de segmentación (núcleo volcado). No puedo entender por qué. He leído que un error de segmentación tiene que ver con acceder a la memoria a la que no tienes acceso. No veo qué podría estar causando eso. Supongo que tiene que ver con los punteros. Soy nuevo en punteros. Gracias.

    #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;
}
Answer

Declaró que un puntero flotaba, pero ese puntero simplemente no apuntaba a nada porque no le asignó una dirección.

cambiar estas lineas

float *start_population;
float *end_population;

a

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

debería solucionar el fallo de segmentación.

Mientras que la otra respuesta te dice la solución, quiero enfatizar la forma de encontrar (y resolver) este tipo de problemas: usa un depurador . Es una herramienta importante de un programador, y es mejor aprender a usarla más temprano que tarde. En este caso, su problema es lo suficientemente simple como para encontrarlo fácilmente con cualquier depurador. Más adelante, cuando trabaje con código más complejo y subprocesos múltiples, será difícil aprender a usarlo mientras intenta resolver su problema (complejo). Por favor, intente resolver este problema por su cuenta utilizando un depurador.

Si está en Linux, puede usar gdb y ejecutar el código hasta que se bloquee. Luego, inspecciona el backtrace ( bt) para ver la última línea ejecutada. Por último, define un punto de interrupción ( p #ndonde #nestá el número de línea) en la línea anterior del bloqueo e inspecciona los valores ( p $variablecon $variableel nombre de su variable) e intenta ver por qué no funciona.

Con un depurador de GUI, debería ser más fácil (por ejemplo, con Visual Studio o Code::blocks).

Cuando declara una variable de puntero f like float *f;, solo puede "usarla" si el puntero apunta realmente a la memoria reservada por usted (el término está asignado). Puede asignar la variable en el "montón" usando la malloc()función o, más fácil, crear una variable separada en la pila (llamada variable automática) escribiendo float my_float;y usando eso. Entonces obtienes:

float my_startfloat;
float *start_population = &my_startfloat;

Dicho esto, solo habría declarado una línea flotante (la primera) y luego, en su caso, usado su dirección: &my_startfloat. Por ejemplo:

 float my_startfloat;
 scanf("%f", &my_startfloat);