分段错误(核心转储),但不知道如何解决

时间:2019-04-13 09:36:00

标签: c struct scanf

当尝试输入一串字符时,我得到警告

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 个答案:

答案 0 :(得分:2)

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] */
    }
    
  • ...以及许多其他组织记忆的方法:)

答案 1 :(得分:0)

doc未分配,因此指向不可预测的位置。您应该将其放在堆栈中:

先评估动态内存。

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

它修复了警告。