Malloc 和 Realloc 不起作用(C11 - CLion)
Malloc and Realloc doesn't work (C11 - CLion)
#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 结构,并且我只能输入一个条目。当我尝试添加一个新条目(switch case:1)时,它不起作用并在本节之后崩溃:
printf("No:");
scanf("%d", &ogrenci[simdikiOgr].no);
起初,我尝试使用 calloc(ogrenciSayisi*10*sizeof(Ogr)) 但它只创建了一个 space。之后,在 realloc 部分之后的调试器(CLion)中,ogrenci 指针变为空指针。
编辑:
我不是要 return 一个值。据我所知 (int a) 等于 (int a[ ]) 所以 KayitEkle(ogrenci) 和 void KayitEkle (Ogr ogrenci) 对我来说似乎是合法的。我的 ogrenci 首先应该是空的,所以 (Ogr *ogrenci=NULL) 是正确的,就像你说的那样吗?
编辑2:
在 malloc 中,第 10 节是一个错误。我修好了它。我正在尝试一些东西,但我忘了删除它。
您将 ogrenci
指针按值传递给 KayitEkle()
,您在其中修改了它的值,但没有 return 它被修改为 main()
的值。您需要使用指针传递 ogrenci
值(即 KayitEkle(&ogrenci)
)或 return 将新值传递给被调用方(即 ogrenci = KayitEkle(ogrenci)
)。下面的例子是后者。
ogrenci
指针在 while 循环内,因此每次循环运行时都会重新初始化它,可能您打算将它放在循环之外,以便保留它的值。
局部变量具有 undefined(阅读:any)值而无需初始化,因此如果需要,您需要将 ogrenci 显式初始化为 NULL。参见 Initialization。
当 ogrenci == NULL
时,您不需要检查 ogrenciSayisi == 0
,因为 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;
}
错误较多。如果你想用你的函数动态分配内存。必须使用指针的指针,例如realloc 行上的指令也不正确,因为如果重新分配失败,您将覆盖旧的内存地址并且指针采用与 NULL 相同的值。
并且没有偏离主题。如果您输入格式所期望的内容以外的任何内容 (例如,字符而不是数字,反之亦然),您还应该对 scanf 函数采取预防措施,确保该程序的行为不确定,所以你应该预料到这种情况。
#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 结构,并且我只能输入一个条目。当我尝试添加一个新条目(switch case:1)时,它不起作用并在本节之后崩溃:
printf("No:");
scanf("%d", &ogrenci[simdikiOgr].no);
起初,我尝试使用 calloc(ogrenciSayisi*10*sizeof(Ogr)) 但它只创建了一个 space。之后,在 realloc 部分之后的调试器(CLion)中,ogrenci 指针变为空指针。
编辑: 我不是要 return 一个值。据我所知 (int a) 等于 (int a[ ]) 所以 KayitEkle(ogrenci) 和 void KayitEkle (Ogr ogrenci) 对我来说似乎是合法的。我的 ogrenci 首先应该是空的,所以 (Ogr *ogrenci=NULL) 是正确的,就像你说的那样吗?
编辑2: 在 malloc 中,第 10 节是一个错误。我修好了它。我正在尝试一些东西,但我忘了删除它。
您将 ogrenci
指针按值传递给 KayitEkle()
,您在其中修改了它的值,但没有 return 它被修改为 main()
的值。您需要使用指针传递 ogrenci
值(即 KayitEkle(&ogrenci)
)或 return 将新值传递给被调用方(即 ogrenci = KayitEkle(ogrenci)
)。下面的例子是后者。
ogrenci
指针在 while 循环内,因此每次循环运行时都会重新初始化它,可能您打算将它放在循环之外,以便保留它的值。
局部变量具有 undefined(阅读:any)值而无需初始化,因此如果需要,您需要将 ogrenci 显式初始化为 NULL。参见 Initialization。
当 ogrenci == NULL
时,您不需要检查 ogrenciSayisi == 0
,因为 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;
}
错误较多。如果你想用你的函数动态分配内存。必须使用指针的指针,例如realloc 行上的指令也不正确,因为如果重新分配失败,您将覆盖旧的内存地址并且指针采用与 NULL 相同的值。
并且没有偏离主题。如果您输入格式所期望的内容以外的任何内容 (例如,字符而不是数字,反之亦然),您还应该对 scanf 函数采取预防措施,确保该程序的行为不确定,所以你应该预料到这种情况。