Malloc and Realloc doesn't work (C11 - CLion)

1.3k Views Asked by At
#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;
}

As u can see, I use malloc() and realloc() for my typedef struct and I'm able to enter only one entry. When I tried adding a new entry (switch case: 1) it doesn't work and crashes after this section:

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

At first, I tried I used calloc(ogrenciSayisi*10*sizeof(Ogr)) but it was created only one space. After that, in the debugger (CLion's) after realloc section, ogrenci pointer becomes a null pointer.

Edit: I'm not trying to return a value. As I know (int a) equals (int a[ ]) so KayitEkle(ogrenci) and void KayitEkle (Ogr ogrenci) seems legit to me. And my ogrenci should be empty in the first place so (Ogr *ogrenci=NULL) is correct as you said right?

Edit2: In malloc section 10 is a mistake. I fixed it. I was trying something and I forgot to delete it.

2

There are 2 best solutions below

0
KamilCuk On BEST ANSWER

You pass ogrenci pointer by value to KayitEkle(), you modify it's value inside it, yet not return it's modified value to main(). You need to pass ogrenci value using a pointer (ie. KayitEkle(&ogrenci)) or return the new value to the called (ie. ogrenci = KayitEkle(ogrenci)). Example below is with the latter. ogrenci pointer is inside the while loop, so it will be reinitialized every time the loop runs, probably you meant to put it outside of the loop so it's value is preserved. Local variables have undefined (read: any) value without initialization, so you need to explicitly initialize ogrenci to NULL, if you need. See Initialization. You don't need to check for ogrenciSayisi == 0 when ogrenci == NULL, because realloc(NULL, ...) is equal to malloc(...). See 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;
}
0
sambia39 On

There are many mistakes. If you want to dynamically allocate memory with your function. A pointer of pointer must be used e.g. The instructions on the realloc line are also not correct, because if your re-allocation fails, you overwrite the old memory address and the pointer takes the same value as NULL.

And without getting off topic. You should also take precautions with the scanf function if you enter anything other than what the format expects (e.g. characters instead of numbers or vice versa), it is sure that the program will behave indeterminately, so you should anticipate this scenario.