Reputation: 45
I'm trying to solve my home-work in C which asks me to make a function that puts a char value in the correct place in a sorted linked list.
actually I don't really get the difference in the function header between making it struct typedef name *struct
and struct typedef name **struct
.
When I look at my teacher's solution she did that with **
, and don't understand the meaning of that.
void insert_in_sorted_list(Node *lst, char x) {
Node *temp;
while (lst) {
if (x > lst->value && x < lst->next->value) {
temp = (Node*)malloc(sizeof(Node));
temp->value = x;
temp->next = lst->next;
lst->next = temp;
}
else lst = lst->next;
}
}
Upvotes: 1
Views: 2563
Reputation: 386
When you accept an argument with a *
you are actually accepting the address to something (this is called a pointer). If you accept a argument with **
you are accepting a pointer to a pointer.
So this:
void insert_in_sorted_list(Node *lst, char x)
Is accepting a pointer to a Node
and this:
void insert_in_sorted_list(Node **lst, char x)
is accepting a pointer to a pointer to a Node
.
Your implementation will work if we have a list already created and we are not adding to the front or back of the list. But consider what might happen if you need to change the first item in the list. If the user has a pointer to the first node in the list and passes it to the function and the new node needs to be inserted in front of the fist node the function could insert it properly in front of the first node but when the user looks at the list after using this function they will still have a pointer to that same Node
(shouldn't be first anymore) and be unaware a node exists in front of it. So the user will need to pass a pointer to the pointer to the first node, that way the pointer to the first Node
can be changed.
Updating your code to accept a pointer to a pointer to a Node
, now you need to access a pointer to a node with *lst
instead of just lst
void insert_in_sorted_list(Node ** lst, char x)
Another thing to consider what if the user has an empty list, nothing will get inserted.
Consider what would happen if we get to the last node, ie lst->next
is NULL, when we try to access lst->next->value
we will have some sort of NULL pointer exception. Even if we didn't will this code insert another node at the end?
Upvotes: 0
Reputation: 52659
If you pass a struct to a function, because every function take a copy, you cannot change the original data. So you typically pass a pointer to the struct, this means any change you make is applied to the original data. ie you don't update a by-value copy, you update the old memory struct in-place.
However, sometimes there is no struct yet (because you want to construct one in the function for example) so there's no way of telling the caller where you put this new struct. So you have to pass a **
to say "I've created this struct, and its here" and then pass that location to the caller. ie you point to the memory where the struct is created, and pass that location back via the "pointer to" parameter trick.
You cannot simply pass in a pointer to the struct, because that is passed to the function by value, ie copied. so when the function exits, the old pointer value is kept. Hence pointer-to-pointer.
Pointers are conceptually awkward, IMHO the best way to think of them is as an integer value that contains a memory location (which is what they actually are) rather than trying to understand them as some abstract concept. That can hep understand things like performance and memory copying a lot too.
Upvotes: 1
Reputation: 70513
The easy way to think about it is that * <something>
means pointer to something and '** ` means pointer to a pointer to something.
Since c is pass by value the only way to "change" a parameter is to pass a pointer to it.
So a function with a ** something is going to change what the pointer points to in the function.
Upvotes: 0