I have a array of structs in the main function and I would like to save data of few structs. I'm using a function that receive the wanted data and put it into struct that is defined into the function. At the end of the process I return the address of this struct. But if I call to this function few times ,it always defines the same address of the struct so I am losing a data of the previous call.
#include<stdio.h>
struct data {
int day;
};
struct data* Dates(int val);
int main() {
struct data* Dates1[3];
int array[] = { 12, 15, 2021 };
for (int i = 0; i < 3; i ) {
Dates1[i] = Dates(array[i]);
}
}
struct data* Dates(int val) {
struct data Date;
Date.day = val;
return &Date; ///AFTER EVERY CALL TO THIS FUNCTION IT RETURN THE SAME ADDRESS!!!
}
CodePudding user response:
When you call a function, it creates a stack frame. Local variables to that function are allocated within that stack frame. When the function exits, the stack frame is "destroyed". That memory can be reused.
You're seeing this behavior because each time you call the function in your loop, it reuses the same memory space.
You cannot rely on the validity of an address to a variable allocated on the stack outside of the current function call. If you need a value to live on after the function call, you need to dynamically allocate it - typically with malloc
. Just don't forget to free
that memory when you're done with it.
CodePudding user response:
You have to write you function as something like this:
struct data* Date = (struct data*) malloc(sizeof(struct data))
Date->day = val;
return Date;
Afterwards you have to call free() on the pointer when it is no longer used. (if not this is called a memory leak)
When you are confused keep in mind the simple rule that you can only return pointers up to that call level where the variable pointing too was created. If you want to learn why this is, you should read up on what a call stack is and how stack variables work.
CodePudding user response:
If you don't want to use malloc
, an alternative is have the function take in a pointer to the uninitialized value, void Dates(struct data *, int);
, then the caller is responsible for the memory.
#include <stdio.h>
#include <assert.h>
struct data {
int day;
};
static void Dates(struct data *const data, const int val) {
assert(data); /* Defensive debug. */
data->day = val;
}
int main(void) {
int array[] = { 12, 15, 2021 };
struct data dates1[sizeof array / sizeof *array];
for(int i = 0; i < sizeof dates1 / sizeof *dates1; i )
{
Dates(dates1 i, array[i]);
printf("%d: %d\n", i, dates1[i].day);
}
}
This can be better suited for when one wants a memory-allocation-agnostic function; in this example, I've reserved memory on the heap instead of dynamically.