I’m solving questions from my C/C++ questions catalogue and stumbled upon the following question:
Give the structure:
typedef struct {
int day, month;
} Birthday;
which of the following two functions is correct? Elaborate why.
Birthday *date_new(int day, int month) {
Birthday birthday;
birthday.day = day;
birthday.month = month;
return &birthday;
}
and
Birthday *date_new(int day, int month) {
Birthday *birthday = malloc(sizeof(*birthday));
birthday->day = day;
birthday->month = month;
return birthday;
}
My answer would be that the second function is correct, because the first one yields warning: function returns address of local variable, but to me both seem alright, because what matters is that we return a pointer, which we also do in the first function. So what’s wrong with the first function?
>Solution :
The object birthday is a local object of the first function with automatic storage duration.
Birthday *date_new(int day, int month) {
Birthday birthday;
birthday.day = day;
birthday.month = month;
return &birthday;
}
It means that it will not be alive after exiting the function and as a result the returned pointer will be invalid.
From the C Standard (6.2.4 Storage durations of objects_)
2 The lifetime of an object is the portion of program execution during
which storage is guaranteed to be reserved for it. An object exists,
has a constant address,33) and retains its last-stored value
throughout its lifetime.34) If an object is referred to outside of
its lifetime, the behavior is undefined. The value of a pointer
becomes indeterminate when the object it points to (or just past)
reaches the end of its lifetime.
In the second function the object of the structure type is allocated dynamically.
Birthday *birthday = malloc(sizeof(*birthday));
It has allocated storage duration and will be alive after exiting the function. So the returned pointer will be valid and will point to the dynamically allocated object.