0

this is a struct in my code

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;
};

this is one of my function

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;
}

this is one the function called in function above

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;
}

input for name is: testing

the output at printf("\n%s", detail.name) is

testing

and the output at printf("\n%s %d", detail.name, detail.year) will be garbage value.

why the detail.name returned a garbage value? and at the end comes out with different garbage value when the struct custDetail go on pass through all the function.

2 Answers 2

2

Lets take a look at these lines from your promptDetail function:

char name[100];
detail.name = name;

The first line above defined name as an array within the scope of the promptDetail function. Its life-time ends with the end of the promptDetail function.

The second line makes detail.name point to the first element of name.

That means once the function promptDetail and the name array (in a way) cease to exist, that pointer will no longer be valid. Attempting to dereference that pointer (like what happens if you print the "string" it's supposedly point to) will lead to undefined behavior.

Sign up to request clarification or add additional context in comments.

Comments

1

In your code

char name[100];

is local to the function promptDetail() and have automatic storage duration.

Inside the function, you use the struct member name to hold the address of the array

detail.name = name;

and later, upon returning from the function, you try to use the content present in that address.

Whereas, in reality, the array being a local array with automatic storage duration, reaches end of it's lifetime and after returning from the function call, inside the caller, the address is not valid anymore. Hence, you access an invalid memory and invoke undefined behavior.

Seeing some garbage value is just another notion of the undefined behavior.

Solution: You have to either

  • Make the local array have static storage duration, so as the lifetime of the array is till end of the program (i.e., the address remain valid after returning from the function call)
  • use a pointer, call memory allocator functions to allocate memory and use that memory to store the value. Then, in the caller, once you're done using the value you have to free() the previously allocated memory.
  • use an array as the member variable, instead of a pointer. You can then, scan and put the value in the array member, and use it in the caller.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.