Określ błąd powodujący błąd segmentacji (reset jądra)

0

Pytanie

Jestem początkujący w programowaniu w c. Postanowiłem, że będę uczyć się, wykonując niektóre z zadań postawionych w otwartym kursie cs50. Poniższy kod generuje błąd błąd segmentacji (reset jądra). Nie mogę zrozumieć, dlaczego. Czytałem, że błąd segmentacji związane z dostępem do pamięci, do którego nie masz dostępu. Nie rozumiem, co mogło być tego przyczyną. Zakładam, że jest to związane ze wskaźnikami. Jestem nowy w drogowskazami. Dziękuję.

    #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

Wpłaciłaś indeks zmiennoprzecinkowych, ale ten wskaźnik jest po prostu na nic nie wskazywał, bo nie wyznaczono mu adres.

Zmień te wiersze

float *start_population;
float *end_population;

Dla

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

należy usunąć błąd segmentacji.

2021-11-24 08:35:58
0

W czasie, gdy inna odpowiedź podpowiada ci rozwiązanie, chcę podkreślić sposób wyszukiwania (i rozwiązania) tego rodzaju problemów: użyj debugera. Jest to ważne narzędzie programisty, i najlepiej nauczyć się go używać wcześniej, niż później. W tym przypadku problem jest na tyle prosta, aby można było ją łatwo znaleźć za pomocą dowolnego debugera. Później, kiedy będziesz pracować z bardziej skomplikowanym kodem i многопоточностью, będzie trudno nauczyć się go używać, aż próbujesz rozwiązać swoje (złożony) problem. Proszę spróbować samodzielnie rozwiązać ten problem za pomocą debuggera.

Jeśli pracujesz w systemie Linux, można używać gdb i uruchomić kod, dopóki on się nie zawiesi. Następnie sprawdzasz drogę powrotną (bt) , aby zobaczyć ostatnią linię. Wreszcie, można określić punkt przerwania (p #n gdzie #n jest numerem wiersza) w poprzednim wierszu awarii, i sprawdzasz wartości (p $variable z $variable nazwa zmiennej) i staraj się zrozumieć, dlaczego to nie działa.

Z tego narzędzia interfejsu graficznego, to powinno być łatwiejsze (np. z Visual Studio lub Code::blocks).

2021-11-24 08:58:20
0

Kiedy zadeklarować zmienną wskaźnika f mniej więcej tak float *f; można go "używać" tylko w przypadku, gdy wskaźnik naprawdę wskazuje na rezerwującej pamięć (termin zaznaczony). Możesz wybrać zmienną w "kupie", za pomocą malloc() funkcja lub, mówiąc prościej, utwórz oddzielną zmienną w stosie (zwaną automatycznej zmiennej), pisząc float my_float; i wykorzystujesz to. W ten sposób można uzyskać:

float my_startfloat;
float *start_population = &my_startfloat;

Nie mniej jednak, ja bym ogłosił tylko pływającą (pierwszej) wiersz, a następnie, w razie potrzeby, użył jej adres: &my_startfloat. Na przykład:

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

W innych językach

Ta strona jest w innych językach

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