I have been trying to study some examples concerning the management of simple singly linked lists from the book: "mastering algorithms with C". Here are some of the questions that I have come across:
I am not able to follow some of the code given to manage a simple linked list. to be specific, the prototype for the function which initializes the list is as follows:
CPP / C++ / C Code:
Code:
[void list_init(List *list,void (*destroy)(void *data));
here the struct list looks like:
CPP / C++ / C Code:
Code:
[typdef struct Listelmt_ {
void *data;
struct ListElmt_ *nest;
} Listelmt;
typedef struct List_ {
int size;
int (*match)(const void *key1,const void *key2);
void (*destroy)(void *data);
Listelmt *head;
Listelmt *tail;
} List;]
What I do not understand is the statement which reads:
the destroy argument provides a way to free dynamically allocated data when List_destroy is called.for ex. if the list contains data dynamically alocated using malloc, destroy argument should be set to free to free the data as the list is destroyed........
Does it imply that one should call this function with one of the arguments being the standard free function which has a similar prototype as that of the destroy function pointer above? If yes then why are we declaring destroy as a function pointer and not a plain function?
next question:
there is a function used to remove an element after a given element in the linked list which is declared as:
CPP / C++ / C Code:
Code:
[nt list_rem_next(List *list, Listelmt *element, void **data);]/
where the typedefs for Listelmt and List hold from the above mentioned source code. As data in the definition of Listelmt was declared a pointer to void; it is obvious that in order to modify that pointer we need to pass a pointer to it which is exactly what the local variable data in the function prototype for list_rem_next above stands for.
Now this function is used in the definition of a certain function called list_destroy wherein it is called in the following way:
CPP / C++ / C Code:
Code:
[if (list_rem_next(list, NULL, (void **)&data) == 0 && List -> Destroy != NULL)]/
now this function list_destroy actually has a variable called data which is actually a void pointer i.e.
CPP / C++ / C Code:
From that one can conclude that , while calling the function list_rem_next he has casted this void pointer into a type which is a pointer to a void pointer; isn't it?
But when one appends the '&' sign with the 'data' variable, which has already been declared to be a void pointer, wouldn't it automatically mean that we need the address of 'data' and '&data' would automatically be of the type "pointer to a pointer to void" isn't it?
Why then has the author chose to cast it explicitly into that type when it happens automatically? Am i understanding it correctly or is it something else?
Waiting for comments from anybody who reads this::
Nishant tiwari