I need to create unique instances of a struct and return its address without using malloc.
The problem is everytime I call the function that creates the struct instance, the address to the instance is the same.
inside of List.h
typedef struct List_s List;
struct List_s{
Node* next;
};
inside of List.c
List* List_Create(){
static List head;
printf("%p\n", &head); <--- In both function calls prints out the same address
return NULL;
}
int main(void){
List_Create();
List_Create(); // I
}
I have tried not using the static keyword but the same problem occurs. Additionally, I have put initialized the List struct outside of the function and no problem occurs, but I need to do it inside of a function.
CodePudding user response:
This is a very simple implementation that uses a fixed-size static array, and returns a pointer to an element of it.
List* List_Create(){
static List lists[MAX_LISTS];
static int index = 0;
if (index >= MAX_LISTS) {
return NULL;
}
// initialze contents of lists[index] here
return &lists[index ];
}
If you also need to be able to destroy lists to the pool you'll need to make lists
a global variable, so it can be used by both List_Create
and List_Destroy
. And you'll need some way of keeping track of which elements have been destroyed. You could wrap each List
in another struct that has an in_use
member.
CodePudding user response:
By using static
, there is only one instance, with lifetime for the duration of the process.
Without static
you are creating an instance with lifetime for the duration of that specific call. Returning an pointer to that instance us invalid, it's memory is available for reuse.
To do that without heap allocation would require a pool of instances. For example:
#define MAX_LISTS 200
List* List_Create( void )
{
static List list_pool[MAX_LISTS] ;
static size_t next_list = 0 ;
List* list = NULL ;
if( next_list < MAX_LISTS )
{
list = &list_pool[next_list] ;
}
return list ;
}
The above is a very crude example, it has no means of returning list to the pool, which may be a requirement. To do that you would need to move the static
s outside of the function and have a means of marking an element used/unused, and a means of searching for an unused element on "creation". However the point is that you need a pool, the precise implementation is beyond the scope of this question I think.