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
数组(以某种方式)停止存在,该指针将不再有效。正在尝试取消引用该点