Ошибка сегментации (дамп ядра), но не знаю, как ее исправить - PullRequest
0 голосов
/ 13 апреля 2019

При попытке ввода строки символов я получаю предупреждение

warning: 'doc' may be uninitialized in this function [-Wmaybe-uninitualized]

Когда я запускаю код, он позволяет мне только ввести саму строку и затем останавливается.

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

#include <stdio.h>
#include <string.h>

typedef struct Pacient{
    char ime_prezime[100];
    int osiguruvanje;
    int broj_pregledi;
}Pacient;

typedef struct MaticenDoktor{
    char ime_prezime[100];
    int broj_pacienti;
    Pacient pacient[200];
    float cena;
}MaticenDoktor;

void najuspesen_doktor(MaticenDoktor *doc, int n){
    int i, j, najgolema_zarabotka=0, najmnogu_pregledi=0, zarabotka, pregledi;
    char najuspesen[100];
    for(i=0; i<n; i++){
        zarabotka=0;
        pregledi=0;
        for(j=0; j<doc[i].broj_pacienti; j++){
            if(doc[i].pacient[j].osiguruvanje==0){
                zarabotka+=doc[i].cena;
                pregledi++;
            }
        }
        if(zarabotka>najgolema_zarabotka){
            najgolema_zarabotka=zarabotka;
            strcpy(najuspesen, doc[i].ime_prezime);
            najmnogu_pregledi=pregledi;
        }
        else if(zarabotka==najgolema_zarabotka){
            if(pregledi>najmnogu_pregledi){
                najgolema_zarabotka=zarabotka;
                strcpy(najuspesen, doc[i].ime_prezime);
                najmnogu_pregledi=pregledi;
            }
        }
    }
    printf("%s %d %d", najuspesen, najgolema_zarabotka, najmnogu_pregledi);
}

int main()
{
    int i, j, n;
    printf("Vnesi broj na doktori\n");
    scanf("%d", &n);
    MaticenDoktor *doc;
    for(i=0; i<n; i++){
        scanf("%s", doc[i].ime_prezime);   //  <---- warning here
        scanf("%d", &doc[i].broj_pacienti);
        scanf("%f", &doc[i].cena);
        for(j=0; j<doc[i].broj_pacienti; j++){
            scanf("%s", doc[i].pacient[j].ime_prezime);
            scanf("%d", &doc[i].pacient[j].osiguruvanje);
            scanf("%d", &doc[i].pacient[j].broj_pregledi);
        }
    }
    najuspesen_doktor(doc, n);
    return 0;
}

Кто-нибудь знает, как это исправить?

Ответы [ 2 ]

2 голосов
/ 15 апреля 2019

MaticenDoktor *doc; объявляет только указатель, а не полную структуру (или массив).Вам нужно инициализировать его так, чтобы он указывал куда-то, где вы можете гарантировать, что достаточно свободной памяти для хранения информации.Вы можете убедиться в этом несколькими способами:

  • Вместо этого вы можете сохранить полную структуру в теле функции (main в вашем случае, с помощью такого же объявления:

    MaticenDoktor doc; /* no pointer, but a full structure variable is declared */
    scan("%s", doc.ime_prezime);
    ...
    
  • Вы можете объявить массив структур MaticenDoktor со следующим кодом:

    MaticenDoktor doc[100];  /* now doc is an array with space for 100 MaticenDoktors */
    scan("%s", doc[n].ime_prezime); /* n ranges from 0 to 99 max */
    
  • Вы можете, если вы этого не сделаетезнать априори сколько MaticenDoktor у вас будет, и вы прочитаете его перед циклом, с:

    MaticenDoktor *doc = malloc(n * sizeof *doc); /* you have doc pointing to an array of n MaticenDoktors */
    scan("%s", doc[n].ime_prezime);
    ...
    free(doc); /* after you are completely finished using doc */
    
  • Вы можете, если выне хватает памяти, просто объявите массив указателей с пробелом для максимума и выделите структуры по мере необходимости:

    MaticenDoktor *doc[1000]; /* space for maximum of 1000 pointers to MaticenDoktor */
    for (i = 0; i < n && i < 1000; i++) {
        doc[i] = malloc(sizeof *doc[i]); /* size of pointed value, not of pointer */
        scanf("%s", doc[i]->ime_prezime);
        ...
    }
    

    и позже

    for (i = 0; i < n && i < 1000; i++) {
         free(doc[i]); /* free space used by doc[i] */
    }
    
  • ... и многие другие способы организации вашей памяти:)

0 голосов
/ 13 апреля 2019

doc не был назначен, поэтому указывает на непредсказуемое местоположение.Вы должны либо поместить его в стек:

сначала заполняя динамическую память.

MaticenDoktor *doc;
int len = 10; // all memory that you need.
doc =(MaticenDoktor *)malloc(sizeof(MaticenDoktor)*len);

это исправит предупреждение.

...