Malloc和Realloc不起作用(C11 - CLion)

时间:2018-05-07 08:30:26

标签: c struct malloc realloc dynamic-allocation

#include <stdio.h>
#include <stdlib.h>

typedef struct Ogrenciler {
    int no;
    char adi[50];
    char soyadi[50];
    double vize;
    double final;
    double notu;
} Ogr;

int ogrenciSayisi = 0;

void KayitEkle(Ogr *ogrenci) {
    int simdikiOgr = ogrenciSayisi;
    if (ogrenciSayisi == 0) {
        ogrenciSayisi++;
        ogrenci = (Ogr *) malloc(ogrenciSayisi*sizeof(Ogr));
    } else {
        ogrenciSayisi++;
        ogrenci = (Ogr *) realloc(ogrenci, ogrenciSayisi * sizeof(Ogr));
    }
    printf("No:");
    scanf("%d", &ogrenci[simdikiOgr].no);
    printf("Adi:");
    scanf("%s", ogrenci[simdikiOgr].adi);
    printf("Soyadi:");
    scanf("%s", ogrenci[simdikiOgr].soyadi);
    printf("Vize:");
    scanf("%lf", &ogrenci[simdikiOgr].vize);
    printf("Final:");
    scanf("%lf", &ogrenci[simdikiOgr].final);
    ogrenci[simdikiOgr].notu = (ogrenci[simdikiOgr].vize * 0.4) + (ogrenci[simdikiOgr].final * 0.6);
    printf("Notu: %lf", ogrenci[simdikiOgr].notu);
    printf("\n\n");
    printf("Adi: %s\nNo: %d\nVize: %lf\nFinal: %lfNotu: %lf\n",
           ogrenci[simdikiOgr].adi, ogrenci[simdikiOgr].no, ogrenci[simdikiOgr].vize, ogrenci[simdikiOgr].final,
           ogrenci[simdikiOgr].notu);
}

int main() {
    int c;
    while (c != 5) {
        printf("\n1-\tYeni Kayit Ekle\n2-\tKayit Sil\n3-\tKayitlari Listele\n4-\tOrtalama Hesapla\n5-\tCikis\n");
        scanf(" %d", &c);
        Ogr *ogrenci;
        switch (c) {
            case 1:
                KayitEkle(ogrenci);
                break;
            case 2:
                KayitSil(ogrenci);
                break;
            case 3:
                KayitListele(ogrenci);
                break;
            case 4:
                OrtHesapla(ogrenci);
                break;
            case 5:
                printf("Cikiliyor");
                break;
            default:
                printf("Gecerli bir girdi yapiniz\n");
                break;
        }
    }

    return 0;
}

正如你所看到的,我使用malloc()和realloc()作为我的typedef结构,我只能输入一个条目。当我尝试添加一个新条目(开关案例:1)时,它不起作用并在此部分后崩溃:

printf("No:");
scanf("%d", &ogrenci[simdikiOgr].no);

起初,我尝试使用calloc(ogrenciSayisi * 10 * sizeof(Ogr)),但它只创建了一个空格。之后,在realloc部分之后的调试器(CLion)中,ogrenci指针变为空指针。

编辑: 我不是想要返回一个值。据我所知(int a)equals(int a [])所以KayitEkle(ogrenci)和void KayitEkle(Ogr ogrenci)似乎对我来说是合法的。而且我的ogrenci首先应该是空的,所以(Ogr * ogrenci = NULL)是正确的,如你说的那样吗?

EDIT2: 在malloc部分10中是一个错误。我修好了它。我正在尝试一些东西而且我忘了删除它。

2 个答案:

答案 0 :(得分:1)

您将ogrenci指针按值传递给KayitEkle(),您可以在其中修改它的值,但不会将其修改后的值返回main()。您需要使用指针(即ogrenci)传递KayitEkle(&ogrenci)值或将新值返回给被调用者(即。ogrenci = KayitEkle(ogrenci))。下面的例子是后者。 ogrenci指针位于while循环内部,因此每次循环运行时它都会重新初始化,可能你的意思是把它放在循环之外,这样就保留了它的值。 局部变量在没有初始化的情况下具有 undefined (读取:任何)值,因此如果需要,您需要将ogrenci显式初始化为NULL。见Initialization。 您ogrenciSayisi == 0时无需检查ogrenci == NULL,因为realloc(NULL, ...)等于malloc(...)。请参阅realloc

#include <stdio.h>
#include <stdlib.h>

typedef struct Ogrenciler {
    int no;
    char adi[50];
    char soyadi[50];
    double vize;
    double final;
    double notu;
} Ogr;

int ogrenciSayisi = 0;

// or void KayitEkle(Ogr **ogrenci) and then use *ogrenci
Ogr *KayitEkle(Ogr *ogrenci) {
    int simdikiOgr = ogrenciSayisi;

    ogrenciSayisi++;
    ogrenci = realloc(ogrenci, ogrenciSayisi*sizeof(Ogr));

    printf("No:");
    scanf("%d", &ogrenci[simdikiOgr].no);
    printf("Adi:");
    scanf("%s", ogrenci[simdikiOgr].adi);
    printf("Soyadi:");
    scanf("%s", ogrenci[simdikiOgr].soyadi);
    printf("Vize:");
    scanf("%lf", &ogrenci[simdikiOgr].vize);
    printf("Final:");
    scanf("%lf", &ogrenci[simdikiOgr].final);
    ogrenci[simdikiOgr].notu = (ogrenci[simdikiOgr].vize * 0.4) + (ogrenci[simdikiOgr].final * 0.6);
    printf("Notu: %lf", ogrenci[simdikiOgr].notu);
    printf("\n\n");
    printf("Adi: %s\nNo: %d\nVize: %lf\nFinal: %lfNotu: %lf\n",
           ogrenci[simdikiOgr].adi, ogrenci[simdikiOgr].no, ogrenci[simdikiOgr].vize, ogrenci[simdikiOgr].final,
           ogrenci[simdikiOgr].notu);
    return ogrenci;
}

int main() {
    int c = 0;
    Ogr *ogrenci = NULL;
    while (c != 5) {
        printf("\n1-\tYeni Kayit Ekle\n2-\tKayit Sil\n3-\tKayitlari Listele\n4-\tOrtalama Hesapla\n5-\tCikis\n");
        scanf(" %d", &c);
        switch (c) {
            case 1:
                ogrenci = KayitEkle(ogrenci);
                break;
            case 2:
                ogrenci = KayitSil(ogrenci);
                break;
            case 3:
                ogrenci = KayitListele(ogrenci);
                break;
            case 4:
                ogrenci = OrtHesapla(ogrenci);
                break;
            case 5:
                printf("Cikiliyor");
                break;
            default:
                printf("Gecerli bir girdi yapiniz\n");
                break;
        }
    }

    // it's nice to free things
    free(ogrenci);

    return 0;
}

答案 1 :(得分:0)

有很多错误。如果要使用函数动态分配内存。必须使用指针指针,例如realloc行上的指令也不正确,因为如果重新分配失败,则覆盖旧的内存地址,指针采用与NULL相同的值。

并且没有脱离主题。如果你输入的格式不是格式所需的东西(例如字符而不是数字,反之亦然),你应该对scanf函数采取预防措施,确保程序的行为不确定,所以你应该这样做预计这种情况。