Reputation: 57
?Hello, I have implemented a struct of link, and with this made a list.
typedef struct link1 {
char* a;
char* b;
int i;
struct link1* next;
};
and I have functions for append, delete etc, from the list. Those functions get the first link in the list. The problem is the after using the functions the information didn't update. Is there a way to pass the parameter of the first link, such that the list will be updated? The first link is from type:
link1* first;
**I have tried to return the first link and it works, but I have nested function and I can't return those links in the external functions, so I think that the only way is to pass the paramter in other way.
Right now I send the parameter like this:
link1* first;
func(first);
void func(link1* l){...}
Thank you!
Upvotes: 0
Views: 296
Reputation: 817
Your problem is that you pass as an attribute in your function, the data of the first node and not the address of the data of your first node. How does this affects us in this case? Any changes you make on the first node, are just changes in a local variable of your function that lives in the stack of your program and when your function returns, this variable will be gone and so the changes you have made.
Check this out, you may understand it better. Imagine that this is a snapshot of your ram and the grey cells are memory indexes and the white cells are the corresponding data:
When you have a variable like b (lets call it a "single pointer" variable) and you pass b as an attribute to a function, you actually pass the data of b (0x1) and not the address of b (0x3). With this in mind, you can notice that you are able to change the contents of 0x1 (for example add 10 and make it '30') but you cannot change the contents of 0x3, which is what you want.
If you want to be able to change the root of your list from a function without returning something, you have to pass the address of the address, or the "double pointer" variable, like c. Passing it like this you are able to:
a) change the data of 0x3: *first = ....
b) change the data of 0x1: **first = ....
If you want to check if understood it, think want is going to happen if you change the data of first. For example:
int **temp = ....;
first = temp;
Now that we mention the theoretical part, in order to follow what i am proposing, you have to change your code into something like this:
func(&first); //pass the address of first variable
.
.
func(<variableType> **first) { // receive with double star
.
.
*first = ...; // change the root using single star
.
.
}
Upvotes: 0
Reputation: 6003
Link list manipulations, such as append, delete, etc., must often affect the "head" node in the list. For example, when the "head" node is deleted, then "head->next" must now assume the role as the new list head node. In such a case, your pointer
link1* first;
(which points to the head node of the list) must be modified to point to the "head->next" node. Unfortunately, passing first to a function in this manor
func(first);
does not allow func() to manipulate where 'first' is pointing. In order for func() to manipulate where 'first' is pointing, you must pass the "address" of first to func():
func(&first);
Now, if func() performs an operation such as 'delete node' or 'add node', it would have the address of 'first', and thereby it can change where 'first' is pointing:
func(struct link1 **first);
{
...
*first = head->next;
...
}
Upvotes: 1
Reputation: 199
Whenever you'd like to change ANYTHING in a function using OUT
BYREF
parameter, u ought to send a pointer to the value that you are setting. I.E: If you were to set an int
then u'd pass int *
; If the value that you are assigning is of type struct link1*
than you ought to pass a pointer to this type (pointer to pointer for the struct) where you can allocate the memory and set the pointer of the calling function.
void init(struct link1 **top)
{
//assign the pointer of the calling function
*top = ...;
}
calling function code
struct link1 *top;
init(&top);
Upvotes: 0