changing address of a pointer array's data - c

I have a tree, each node contains an array children nodes (Node *children_nodes), as well as the name (char *node_name) and parent (Node *parent). each of these are dynamic.
I want to delete a child node from the *children_nodes array, freeing the memory allocated to it's name and children, (let's pretend we are deleting a child with no children), and move the location of the last child of the list to the location of the one we just deleted. how can I do this without making the last node get changed if I want to use the location it was in.
Example- I have a node with three children, I want to free children_nodes[0]'s allocated memory and put children_nodes[2] in that spot, preferably just making children_nodes[0] point to the node of children_nodes[2] and then making children_nodes[2] point to nothing without messing with the node itself.

It's difficult to tell for sure without seeing some code, but I believe you want a Node** children_nodes, so you can just do something like this:
free(children_nodes[0]);
children_nodes[0] = children_nodes[2];
children_nodes[2] = 0;

Related

Inserting an item to a linked list - is iteration necessary (C)?

I'm currently studying linked lists for interview prep, would appreciate if anybody could shed some light on this. The following function in C supposedly inserts a new element into the list after a certain Element elem (passed as an argument to the function):
bool insertAfter(Element * elem, int data){
Element * newElem, * curPos = head;
newElem->data = data;
while(curPos){
if(curPos == elem){
newElem->next = curPos->next;
curPos->next = newElem;
return true;
}
curPos = curPos->Next;
}
return false;
}
Although the above is specified in the textbook I am studying from, I tried coming up with a solution that does not use any iteration whatsoever:
bool insertAfter(Element * elem, int data){
Element * newElem;
newElem->next = elem->next
newElem->data = data
elem->next = newElem;
return true;
}
However, as it appears too simplistic, I sense that it may not work, but am not sure why. I need some insights on the technicalities on why this may or may not work, thanks.
Both versions suffer from the error of using newElem as though it were a valid pointer. It is not. It is not initialized to point to valid object.
You can correct that by allocating memory for an object before using:
Element * newElem = malloc(sizeof(*newElem));
The difference between the two versions is that if elem is not accessible from head for some reason or it is NULL, the first version will do nothing to the existing list. The second version does not deal with either of those scenarios. It assumes that elem is in the list and that it is not NULL.
Your solution is pretty much correct. The iteration in the example is almost completely useless.
What the example function is doing is: given an element to insert the new data after, it looks through the list starting with head to find that same element, then inserts the data - doing nothing with head or elem after finding it. Since all the loop does is "find" an element to which you already had a pointer, it essentially did nothing at all and is useless.
The only possible use of this is to constrain the insertion function to only work on this one list beginning with head, globally, throughout your program. This is such a strange design decision that one would likely assume it's a mistake unless given a reason to believe otherwise (dynamic data structures constrained to a single instance are an unusual pattern; more importantly, the whole point of linked lists is O(1) insertion, which the example function breaks by adding this useless loop). head is not needed for any other reason than to enforce this constraint, and if this is desired, it would make more sense to pass it in as a parameter as well so that the function is able to be used on more than one list per-program. (Or, not to perform the check at all: another use of linked lists is that you can pass around and insert after nodes without worrying about the head element.)
As other people have pointed out, you fail to actually allocate newElem, but so does the textbook. Overall, it's a rubbish example; not only did the author make a mistake with allocation, but they don't appear to understand the basic advantages of using linked lists. You should definitely treat this textbook with suspicion.
Your logic will work, because you just need a pointer to a node where you want to insert a node. If you already have such a pointer, no need to iterate and search for the node.
However the search (iteration) would be relevant if do not have in hand the node pointer where you want to insert the new node. Example: suppose the nodes have unique keys and you do not have the node pointer where the key exists and you want to insert after you find the node containing the specific key, then you need to find the correct node pointer and do the insertion (The function should then take in key as the argument).
However in your code (both cases), you have not allocated the memory for the new node. You need to do malloc for the new node and then go on with the insertion.
This will not work because you do not know your newElem. In linked list you have knowledge about a head and each element gives you information where to find the next one:
head -> e1 -> e2 -> ...
So you need to iterate till you will find the element you care about. But you can also iterate with the recursion.

Design of API's for data structures and algorithms

I recently implemented binary search tree, linked lists etc as a learning exercise. II implemented several API's like Insert,delete etc.
For example the Insert node API looks like
void insertNode(Node** root, Node* node)
The application would allocate memory for the node to be inserted. i.e node and assign the value/key and pass to this function.
1) My question is whether this is right approach in general? Or does the application only need to pass the value/key to insertNode function and the this function allocates memory?
i.e void insertNode(Node** root, int key)
{
malloc for node here
}
2) What is a good design practice- the application handles allocating memory and free or this library of APi's ?
Thanks
General principles:
Whoever allocates memory should also have responsibility to delete it.
Make the client's job as easy as possible
Think about thread safety
So, don't have client allocate the memory being managed by the tree. However we then need to think carefully about what a find or search should return.
You might look at example code to see what policies other folk have taken for collection APIs. For example.
In passing you don't need the double pointer for your root.
If someone has root pointing to an object { left -> ..., right -> ...} then if you pass root as Node* your code can write
root->left = newValue;
you're modifying what root points to not root itself. By passing the double pointer you're allowing the structure to be completely relocated because someone can write:
*root = completelyNewTree
which I doubt you intend.
Now for inserting I'd suggest passing in the new value, but have the collection allocate space and copy it. The collection now has complete control over the data it holds, and anything it returns should be copied. We don't want clients messing with the tree directly (thread safety).
This implies that for result of a find either the caller must pre-allocate a buffer or we must clearly document that the collection is returning an allocated copy that the caller must delete.
And yes, working in any Garbage Collecting language is much easier!

Linked List sentinel node to avoid reassigning pointer to first node

Theory
When deleting a node from a linked list, pointers to the first node in the list will need to be updated if the node being deleted from the list is the first one.
Background
Libevent: how to close all open sockets on shutdown?
Situation
In my server application, a pointer to the first node in a linked list of socket connections is held in a struct holding data related to the context of the running instance, such as listening socket port and so on. When a connection is closed, the related node in the linked list must be removed which means that the function which deletes the node must also access to the instance context struct.
My first ideas were:
Each connection node in the linked list has a pointer to the instance context struct. (Messy.)
Global variable pointer to instance context struct. (Evil.)
Then I had the idea to make the first node in the linked list a sentinel node thereby avoiding the possibility that the first node would ever be removed and therefore side-stepping the need for the socket close function to have access to the instance context.
Question
Is this a suitable use of sentinel nodes or is there a better way to solve this problem?
Is there any meta data about the linked list you'd like to store such as the length of the list? If so, you can store them in the sentinel node.

Create a new copy of a data structure based on pointers

I started with a programming assignment. I had to design a DFA based on graphs. Here is the data structure I used for it:
typedef struct n{
struct n *next[255]; //pointer to the next state. Value is NULL if no transition for the input character( denoted by their ascii value)
bool start_state;
bool end_state;
}node;
Now I have a DFA graph-based structure ready with me. I need to utilize this DFA in several places; The DFA will get modified in each of these several places. But I want unmodified DFAs to be passed to these various functions. One way is to create a copy of this DFA. What is the most elegant way of doing this? So all of them are initialized either with a NULL value or some pointer to another state.
NOTE:
I want the copy to be created in the called function i.e. I pass the DFA, the called function creates its copy and does operation on it. This way, my original DFA remains undeterred.
MORE NOTES:
From each node of a DFA, I can have a directed edge connecting it with another edge, If the transition takes place when there the input alphabet is c then state->next[c] will have a pointer of the next node. It is possible that several elements of the next array are NULL. Modifying the NFA means both adding new nodes as well as altering the present nodes.
If you need a private copy on each call, and since this is a linked data structure, I see no way to avoid copying the whole graph (except perhaps to do a copy-on-write to some sub branches if the performance is that critical, but the complexity is significant and so is the chance of bugs).
Had this been c++, you could have done this in a copy constructor, but in c you just need to clone on every function. One way is to clone the entire structure (Like Mark suggested) - it's pretty complicated since you need to track cycles/ back edges in the graph (which manifest as pointers to previously visited nodes that you don't want to reallocate but reuse what you've already allocated).
Another way, if you're willing to change your data structure, is to work with arrays - keep all the nodes in a single array of type node. The array should be big enough to accommodate all nodes if you know the limit, or just reallocate it to increase upon demand, and each "pointer" is replaced by a simple index.
Building this array is different - instead of mallocing a new node, use the next available index (keep it on the side), or if you're going to add/remove nodes on the fly, you could keep a queue/stack of "free" indices (populate at the beginning with 1..N, and pop/push there whenever you need a new location or about to free an old one.
The upside is that copying would be much faster, since all the links are relative to the instance of the array, you just copy a chunk of contiguous memory (memcpy would now work fine)
Another upside is that the performance of using this data structure should be superior to the linked one, since the memory accesses are spatially close and easily prefetchable.
You'll need to write a recursive function that visits all the nodes, with a global dictionary that keeps track of the mapping from the source graph nodes to the copied graph nodes. This dictionary will be basically a table that maps old pointers to new pointers.
Here's the idea. I haven't compiled it or debugged it...
struct {
node* existing;
node* copy
} dictionary[MAX_NODES] = {0};
node* do_copy(node* existing)
{
node* copy;
int i;
for(i=0;dictionary[i].existing;i++) {
if (dictionary[i].existing == existing) return dictionary[i].copy;
}
copy = (node*)malloc(sizeof(node));
dictionary[i].existing = existing;
dictionary[i].copy = copy;
for(int j=0;j<255 && existing->next[j];j++) {
node* child = do_copy(existing->next[j]);
copy->next[j] = child;
}
copy->end_state = existing->end_state;
copy->start_start = existing->start_state;
return copy;
}

Array to Linked List C

I am trying to convert an array to an linked list.
so basically, im gonna have a structure called "head" which will be the first element
and node, which will be the other elements.
any ideas so i can it started?
I don't see any solution simpler than just iterating through the array and appending the elements to the list.
The standard way to implement linked lists in C is with a single node structure containing a data member and a next pointer. Every time you want a new node, malloc space for it and set the next pointer of the last node in the list to point to it. The last node's next pointer should point to NULL.
You only have to hold onto a regular pointer to the first element. That's your head pointer.
Without using malloc you won't be able to easily add a new node to store data in so its best to just use the array to avoid the mess (but why can't you use malloc now?)

Resources