c中函数的垃圾值
这是我代码中的一个结构c中函数的垃圾值,c,pointers,struct,C,Pointers,Struct,这是我代码中的一个结构 struct custDetail { int reservationID; char *name; int year; int month; int mday; int hour; char *departurePoint; char *destination; char *seatType; char *seat; float price; int airlineID; }
struct custDetail
{
int reservationID;
char *name;
int year;
int month;
int mday;
int hour;
char *departurePoint;
char *destination;
char *seatType;
char *seat;
float price;
int airlineID;
};
这是我的职责之一
void purchaseBusiness();
void purchaseBusiness()
{
struct custDetail detail = { 0 };
detail.seatType = "Business";
detail = promptDetail(detail);
//printf("\n%s", detail.name);
//printf("\n%s %d", detail.name, detail.year);
detail = assignSeat(detail);
detail = confirmDetail(detail);
printf("\n%s", detail.name);
printf("\nBooking success");
displayToFile(detail);
return;
}
这是上面函数中调用的函数之一
struct custDetail promptDetail(struct custDetail);
struct custDetail promptDetail(struct custDetail detail)
{
char name[100];
int flight, departTime;
time_t difference;
printf("\nEnter your name: ");
scanf("%s", name);
detail.name = name;
do
{
printf("\nChoose your flight");
printf("\nPress 1 - KUL to KCH");
printf("\nPress 2 - KCH to KUL");
scanf("%d", &flight);
switch (flight)
{
case 1:
{
detail.departurePoint = "KUL";
detail.destination = "KCH";
printf("\nChoose your departure time");
printf("\nPress 1 - 7:00");
printf("\nPress 2 - 9:00");
scanf("%d", &departTime);
switch (departTime)
{
case 1: detail.hour = 7; break;
case 2: detail.hour = 9; break;
default: printf("\nPlease enter 1 or 2 only"); break;
}
break;
}
case 2:
{
detail.departurePoint = "KCH";
detail.destination = "KUL";
printf("\nChoose your departure time");
printf("\nPress 1 - 19:00");
printf("\nPress 2 - 21:00");
scanf("%d", &departTime);
switch (departTime)
{
case 1: detail.hour = 19; break;
case 2: detail.hour = 21; break;
default: printf("\nPlease enter 1 or 2 only"); break;
}
break;
}
default: printf("\nPlease enter 1 or 2 only");
}
} while ((flight != 1 && flight != 2) || (departTime != 1 && departTime !=
2));
do
{
printf("\nEnter the flight date (dd/mm/yyyy)");
printf("\n30 days and above 10%% discount");
printf("\n90 days and above 15%% discount");
scanf("%d%*c%d%*c%d", &detail.mday, &detail.month, &detail.year);
if (detail.year > 0 && detail.month > 0 && detail.month <= 12 && detail.mday > 0 && detail.mday <= 31)
{
difference = checkDate(detail.year, detail.month, detail.mday, detail.hour);
if (difference < 0)
{
printf("\nPlease enter valid date");
}
}
else
{
printf("\nPlease enter valid date");
difference = -1;
}
} while (difference < 0);
return detail;
}
struct-custdail-promptDetail(struct-custdail);
结构custDetail promptDetail(结构custDetail细节)
{
字符名[100];
国际航班,起飞时间;
时差;
printf(“\n输入您的姓名:”);
scanf(“%s”,名称);
detail.name=名称;
做
{
printf(“\n选择您的航班”);
printf(“\n按1-KUL到KCH”);
printf(“\n按2-KCH到KUL”);
scanf(“%d”和“航班”);
转辙机(航班)
{
案例1:
{
detail.departurePoint=“KUL”;
detail.destination=“KCH”;
printf(“\n选择您的出发时间”);
printf(“\n按1-7:00”);
printf(“\n按2-9:00”);
scanf(“%d”、&departTime);
开关(起飞时间)
{
案例1:detail.hour=7;中断;
案例2:detail.hour=9;中断;
默认值:printf(“\n请仅输入1或2”);break;
}
打破
}
案例2:
{
detail.departurePoint=“KCH”;
detail.destination=“KUL”;
printf(“\n选择您的出发时间”);
printf(“\n按1-19:00”);
printf(“\n按2-21:00”);
scanf(“%d”、&departTime);
开关(起飞时间)
{
案例1:detail.hour=19;中断;
案例2:detail.hour=21;中断;
默认值:printf(“\n请仅输入1或2”);break;
}
打破
}
默认值:printf(“\n请仅输入1或2”);
}
}而((航班!=1&&flight!=2)| |(出发时间!=1&&flight!=2)|
2));
做
{
printf(“\n输入航班日期(dd/mm/yyyy)”);
printf(“\n30天及以上10%%折扣”);
printf(“\n90天及以上15%%折扣”);
scanf(“%d%*c%d%*c%d”、&detail.mday、&detail.month、&detail.year);
如果代码中的(detail.year>0&&detail.month>0&&detail.month 0&&detail.mday
char name[100];
是函数promptDetail()
的本地函数,并具有自动存储持续时间
在函数内部,您可以使用结构成员name
来保存数组的地址
detail.name = name;
稍后,从函数返回时,您将尝试使用该地址中的内容
然而,实际上,该数组是一个具有自动存储持续时间的本地数组,到达其生命周期的末尾,从函数调用返回后,在调用方内部,地址不再有效。因此,您访问无效内存并调用
看到一些垃圾值只是未定义行为的另一个概念
解决方案:您必须
- 使本地数组具有
静态
存储持续时间,使数组的生存期一直到程序结束(即,从函数调用返回后地址保持有效)
- 使用指针,调用内存分配器函数来分配内存并使用该内存存储值。然后,在调用者中,一旦使用完值,就必须
释放()
先前分配的内存
- 使用数组作为成员变量,而不是指针。然后,可以扫描并将值放入数组成员中,然后在调用方中使用它
在您的代码中
char name[100];
是函数promptDetail()
的本地函数,并具有自动存储持续时间
在函数内部,您可以使用结构成员name
来保存数组的地址
detail.name = name;
稍后,从函数返回时,您将尝试使用该地址中的内容
然而,实际上,该数组是一个具有自动存储持续时间的本地数组,到达其生命周期的末尾,从函数调用返回后,在调用方内部,地址不再有效。因此,您访问无效内存并调用
看到一些垃圾值只是未定义行为的另一个概念
解决方案:您必须
- 使本地数组具有
静态
存储持续时间,使数组的生存期一直到程序结束(即,从函数调用返回后地址保持有效)
- 使用指针,调用内存分配器函数来分配内存并使用该内存存储值。然后,在调用者中,一旦使用完值,就必须
释放()
先前分配的内存
- 使用数组作为成员变量,而不是指针。然后,可以扫描并将值放入数组成员中,然后在调用方中使用它
让我们看看您的promptDetail
功能中的这些行:
char name[100];
detail.name = name;
上面的第一行将name
定义为promptDetail
函数范围内的数组。它的生命周期以promptDetail
函数的结尾结束
第二行使detail.name
指向name
的第一个元素
这意味着一旦函数promptDetail
和name
数组(在某种程度上)停止存在,该指针将不再有效。尝试取消对该指针的引用(如打印它应该指向的“字符串”时发生的情况)将导致。让我们从您的promptDetail
功能中查看这些行:
char name[100];
detail.name = name;
上面的第一行将name
定义为promptDetail
函数范围内的数组。它的生命周期以promptDetail
函数的结尾结束
第二行使detail.name
指向name
的第一个元素
这意味着一旦函数promptDetail
和name
数组(以某种方式)停止存在,该指针将不再有效。正在尝试取消引用该点