I have the following question. I have the following structure
typedef struct {
tPilaStackNode *first;
} tPilaStack;
As you can see, it has the following structure
typedef struct tNode {
tPila e;
struct tNode *next;
} tPilaStackNode;
Which in turn contains the following structure:
typedef struct {
tElement element;
} tPila;
(As you can see it does not stop there, however for my example this is enough)
As I can see, if the main element is a stack, therefore what I want is to create a function that adds an element to the stack, that is, a push.
PilaStack_push(tPilaStack *stack, tPila Pila) {
}
My doubt is the following: I have to allocate memory for each struct that is contained, that is:
stack=(struct tPilaStack*)malloc(sizeof(struct tPilaStack))
stack->first=(struct tPilaStack*)malloc(sizeof(struct tPilaStack))
stack->first->next = (struct tNode*)malloc(sizeof(struct tNode));
Or is it enough to do it for a specific level?
As you comment, the memory is reserved with malloc such that:
That is, the number of reserved bytes will depend on the value returned by
sizeof()
.Well, if we have a structure such that:
And we print its size:
It will return us, typically 8, that is, 4 bytes corresponding to
dato1
and another 4 corresponding todato2
.Now let's create a second structure that contains the first:
It will now
sizeof()
return 12, i.e. 4 bytes for eachint
. Nested structures increase the size of the pool .If we now create a second struct pointing to the first:
We see that now it prints 4 (if we are in 32 bits) or 8 (64 bits). That is, by using pointers, you reserve space solely for storing a memory address .
That is, when reserving memory you only have to worry about the pointers, since they will remain pointing to random positions . This can be fixed by replacing
malloc
withcalloc
. The rest of the variables, no matter how many nesting levels you have, will have their own memory address assigned.You should only allocate memory with
malloc
for the node (i.e. for the structtNode
).1. Structure:
We only need to worry about reserving memory
malloc
for this structure (tNode)
. You don't need to allocate memory to the pointer/membernext
, but you do need to have a reference (base address) to the next node.2. Structure:
The structure
tPila
does not need to reserve memory withmalloc
, it can be defined as a local variable and assign the respective data to the member that has the nested structuretElement
.3. Structure:
The structure
tPilaStack
does not need to be created in memory withmalloc
, it can be defined as a simple local variable (it will have an automatic storage, it is created when the function is called and released when the subroutine finishes executing), what if we must take into account, is the memberfirst
. The pointerfirst
must have the memory address of the first attribute/member of the last node. So if this pointer doesn't have a reference that's valid, you'll run into problems at runtime. The content offirst
, will depend on the path of each node of the stack.A possible implementation for the function
PilaStack_push
would be:Let's focus on the parameters
stack
andPila
. Both parameters can be passed a structure variable with automatic or static storage, it does not necessarily have to be dynamic.We would call the function like this:
Functioning:
We assign to the member
first
(of the structuretPilaStack
) a default value, that is,NULL
(remember that the stack must have a node with a member pointing toNULL
to define a start and end in the stack).We assign the value of
10
to the member that has the nested structuretElement
.Lastly, we pass the base address of the struct
tPilaStack
to the first parameter, and to the second, we pass the copy of the struct's contenttPila
.If you notice, I didn't have to reserve memory directly with
malloc
any member.