Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to store and remove dynamically and automatic variable of generic data type in custum list data structure?
    primarykey
    data
    text
    <p>I have created a List data structure implementation for generic data type with each node declared as following. </p> <pre><code>struct Node { void *data; .... .... } </code></pre> <p>So each node in my list will have pointer to the actual data(generic could be anything) item that should be stored in the list. I have following signature for adding a node to the list</p> <pre><code>AddNode(struct List *list, void* eledata); </code></pre> <p>the problem is when i want to remove a node i want to free even the data block pointed by *data pointer inside the node structure that is going to be freed. at first freeing of datablock seems to be straight forward </p> <pre><code>free(data) // forget about the syntax..... </code></pre> <p>But if data is pointing to a block created by malloc then the above call is fine....and we can free that block using free function</p> <pre><code> int *x = (int*) malloc(sizeof(int)); *x = 10; AddNode(list,(void*)x); // x can be freed as it was created using malloc </code></pre> <p>what if a node is created as following</p> <pre><code> int x = 10; AddNode(list,(void*)&amp;x); // x cannot be freed as it was not created using malloc </code></pre> <p>Here we cannot call free on variable x!!!!</p> <p>How do i know or implement the functionality for both dynamically allocated variables and static ones....that are passed to my list....</p> <p>Thanks in advance...</p> <p>The complete implementation is as following list.h simply contains function prototypes.</p> <pre><code>#include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; #include&lt;string.h&gt; #include&lt;assert.h&gt; #include "list.h" //structure of each node static struct Node{ void *Data; struct Node * Next; struct Node * Prev; }; //complete list interface struct List{ int Size; struct Node DummyNode; //dummy node void (*Print)(void *Data); }; //create new List struct List * CreateList(void(*Print)(void* Data)){ struct List *newList = (struct List *)malloc(sizeof(struct List)); if(newList != NULL){ newList-&gt;DummyNode.Data = NULL; newList-&gt;DummyNode.Next = newList-&gt;DummyNode.Prev = &amp;newList-&gt;DummyNode; newList-&gt;Size = 0; newList-&gt;Print = NULL; if(Print != NULL) newList-&gt;Print = Print; // hook to user provided print function return newList; } return NULL; } //Node *ptr point to one node before the actual node to be removed static void _RemoveNode(struct List *list, struct Node *ptr) { struct Node *temp = ptr-&gt;Next; //catch hold of node that is to be removed ptr-&gt;Next = temp-&gt;Next; // link previous node's next pointer with the temp node next pointer temp-&gt;Next-&gt;Prev = ptr; // link next node's previous pointer with previous node pointer temp-&gt;Prev = NULL; // unlink from previous node temp-&gt;Next = NULL; // unlink from next node free(temp-&gt;Data); // free the data ............ !!! need to mode generic before cleaning the resource free(temp); // remove the node itself. list-&gt;Size--; } void RemoveNodeAt(struct List *list,int nodeIndex) { if( list-&gt;Size &gt; 0 &amp;&amp; (nodeIndex &gt;= 0 &amp;&amp; nodeIndex &lt; list-&gt;Size)){ int i=-1; // meaning we are at dummy node struct Node *ptr = NULL; for(ptr = &amp;list-&gt;DummyNode ;i &lt; nodeIndex - 1 ;i++) // traverse up to one node before the actual node ptr = ptr-&gt;Next; _RemoveNode(list,ptr); } } //Node *ptr point to one node before the actual node to be removed static void _AddNode(struct List *list, struct Node *ptr,void *data) { //create New Node struct Node *newNode = (struct Node*)malloc(sizeof(struct Node)); if(newNode != NULL){ newNode-&gt;Data = data; //shift node at index to right newNode-&gt;Next = ptr-&gt;Next; newNode-&gt;Prev = ptr; ptr-&gt;Next = newNode; newNode-&gt;Next-&gt;Prev = newNode; list-&gt;Size++; } } void AddNodeAt(struct List *list,int nodeIndex,void *data) { //A node can be added just before head and just after tail. if( nodeIndex &gt;= 0 &amp;&amp; nodeIndex &lt;= list-&gt;Size){ int i=-1; // meaning we are at dummy node struct Node *ptr = NULL; for(ptr = &amp;list-&gt;DummyNode ;i &lt; nodeIndex - 1 ;i++) // traverse up to one node before the actual node ptr = ptr-&gt;Next; _AddNode(list,ptr,data); } } void RemoveNode(struct List *list) { if(list-&gt;Size &gt; 0){ //check if the list is not empty struct Node * temp = list-&gt;DummyNode.Prev; //catch hold of last node temp-&gt;Prev-&gt;Next = temp-&gt;Next; //establish previous node's next pointer to temp node next pointer temp-&gt;Next-&gt;Prev = temp-&gt;Prev; //establish next node's previous pointer to temp node previous pointer temp-&gt;Next = NULL; // unlink temp node from next node temp-&gt;Prev = NULL; // unlink temp node from previous node free(temp-&gt;Data); // free the data ............ !!! need to mode generic before cleaning the resource free(temp); // remove the node itself. list-&gt;Size--; } } void AddNode(struct List *list,void *data) { struct Node *ptr = list-&gt;DummyNode.Prev; //create New Node struct Node *newNode = (struct Node*)malloc(sizeof(struct Node)); if(newNode != NULL){ newNode-&gt;Data = data; //shift node at index to right newNode-&gt;Next = ptr-&gt;Next; newNode-&gt;Prev = ptr; ptr-&gt;Next = newNode; newNode-&gt;Next-&gt;Prev = newNode; list-&gt;Size++; } } void DeleteAllNodes(struct List *list) { struct Node *ptr = &amp;list-&gt;DummyNode; while(list-&gt;Size &gt; 0){ _RemoveNode(list,ptr); ptr = ptr-&gt;Next; } } void Display(struct List *list) { if(list-&gt;Print != NULL){ //If conusmer doesnot provide a print function just give up printing process. int i=0; struct Node *ptr = &amp;list-&gt;DummyNode; for(i = 0; i &lt; list-&gt;Size; i++){ ptr = ptr-&gt;Next; list-&gt;Print(ptr-&gt;Data); // let the consumer of the list data structure print the way he wants } } } // must be used before inserting automatic variables are passed in to the list // because freeing a automatic variable with free function is a crime....!!!! *(~_~)* // So i want you to create clones of the automatic variables and pass those variables. // AddNode(list,Clone(&amp;i,sizeof(i))); void * Clone(void *data, int size) { void * clone = malloc(size); memcpy(clone,data,size); return clone; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload