I am having some trouble running this linked list implementation (containing words as data). Problem is when I try to print the words (that I inserted) in the Linked List,I get nothing. What am I doing wrong, breaking my head over this? I hope it's not something silly. Anyway here's the code -
typedef struct node
{
void *data;
struct node *next;
} NODE;
NODE *new_node(void *data)
{
NODE *new = malloc(sizeof(NODE));
if(new)
{
new->data = data;
new->next = NULL;
return new;
}
else
{
return NULL;
}
}
void print_list(NODE *head, void (print_fn) (void*))
{
if(head && head->next)
{
while(head->next)
{
if(print_fn)
print_fn(head->data);
else
printf("Word: %s\n", (char *)head->data);
head = head->next;
}
}
return;
}
void append(NODE **head, NODE *node)
{
NODE *tmp = *head;
if(tmp && node)
{
while(tmp->next)
tmp = tmp->next;
(*head)->next = node; /*add as last node*/
}
return;
}
NODE *create_list()
{
FILE *dict_file = fopen("trial.txt", "r");
if(dict_file)
{
NODE *head = new_node(NULL);
if(!head) return NULL;
char word[20];
int first = TRUE;
memset(word, '\0', 20);
while(fgets(word, sizeof(word), dict_file) != NULL )
{
if(first)
{
head->data = (void*)word;
first = FALSE;
}
else
{
append(&head, new_node((void*)word));
}
}
fclose(dict_file);
return head;
}
else
{
printf("ERROR: File not found");
return NULL;
}
}
int main(int argc, char *argv[])
{
NODE *head = create_list();
if(!head)
{
printf("ERROR: Either malloc() failed or data not found\n");
return FALSE;
}
else
{
print_list(head, NULL);
return TRUE;
}
}
This has become quite a long answer. Don't take this personally, but you have made quite a few rookie mistakes. I have met with many people at university whom I helped to learn the C language and programming in general, so I've got used to notice these kinds of things.
The important issues I could find
You assign a pointer to a stack variable to words
This is completely bad, because that value will be overwritten once the execution gets out of the function that creates it. Solution: copy the content of that variable into a heap variable.
Your append function is faulty
It adds the appended element to the second place instead of the last place. Note that you don't need the return at the end either. There is also no point in requiring a double-pointer as input to the append method. Also, after assigning head to tmp, it is futile to check tmp against NULL as well, since it won't be NULL if head isn't NULL. Also, I recommend checking the new node against NULL as well. If it is NULL, this saves you from iterating over the entire collection.
The create_list function is sub-optimal
Fist, the distinction between the first and the other cases are futile. Introducing another pointer (called current in my code) will eliminate the need to check whether it is the first or not. Next, you always call the append function on the head, thus you always need to iterate over the entire collection. This can be also optimized by introducing the current variable. (Which, at start, should be assigned the value of head.)
The print_list function is errornous
It doesn't print anything if there is only one node. It also redundantly checks the pointers for null. (The beginning of the loop checks it, too.) The return statement at the end of this void function is also unnecessary.
You should free up memory when you don't use it
#Baltasarq wrote a nice clear function in his answer, you should use it. :)
Not serious errors, but you should be aware of them
You should not use void* instead of char*
If you know that the data member of the NODE structure is going to store characters, why do you use void*? It is bad practice! (Unless you have a good reason, of course.)
Using the new word as a variable name makes your code not compliant with C++. Thus, I recommend against it.
Adopt a better coding style, please - it will make your code so much easier to read
Inconsistency: if in print_list you don't allocate a new variable to go through the collection (like you do with the tmp variable in append) then it is misguiding to name the parameter as head. (I renamed it to node in my code.)
Here is the fixed code
(Note that there may be small syntax errors because I typed the code into the browser without actually testing it.)
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
void *data;
struct node *next;
} NODE;
NODE *new_node(void *data)
{
NODE *newNode = (NODE*)malloc(sizeof(NODE));
if (newNode)
{
newNode->data = data;
newNode->next = NULL;
return newNode;
}
return NULL;
}
void append(NODE *head, NODE *node)
{
if (head && node)
{
NODE *tmp = head;
while (tmp->next)
tmp = tmp->next;
tmp->next = node; /* add as last node */
}
}
void print_list(NODE *node, void (print_fn) (void*))
{
while (node)
{
if (print_fn)
print_fn(node->data);
else
printf("Word: %s\n", (char *)node->data);
node = node->next;
}
}
NODE *create_list()
{
FILE *dict_file = fopen("trial.txt", "r");
if (dict_file)
{
NODE *head = NULL;
NODE *current = head;
char word[20];
memset(word, '\0', 20);
while (fgets(word, sizeof(word), dict_file))
{
// Creating a variable on the heap
char *data = calloc(sizeof(word) + 1, sizeof(char));
// Copying the contents of words to it
strcpy(data, word);
append(current, new_node((void*)data));
if (current->next)
current = current->next
}
fclose(dict_file);
return head;
}
else
{
printf("ERROR: File not found");
}
return NULL;
}
int main(int argc, char *argv[])
{
NODE *head = create_list();
if (!head)
{
printf("ERROR: Either malloc() failed or data not found\n");
}
else
{
print_list(head, NULL);
}
return 0;
}
Be careful, since malloc() and derivatives can answer with a NULL pointer when there is not enough memory. In fact, take into account that you'll also need a clear() method that free's all the data, as well as the nodes themselves.
void clear(NODE *node)
{
NODE * temp = NULL;
while( node != NULL ) {
temp = node->next;
free( node->data );
free( node );
node = temp;
}
}
Your main() function should return an exit code to the operating system of EXIT_SUCCESS or EXIT_FAILURE, instead of TRUE or FALSE.
int main(int argc, char *argv[])
{
NODE *head = create_list();
int toret = EXIT_SUCCESS;
if(!head)
{
printf("ERROR: Either malloc() failed or data not found\n");
toret = EXIT_FAILURE;
clear( head );
}
else
{
print_list(head, NULL);
clear( head );
}
return toret;
}
Related
Apologies for the very basic question, but I can't figure this out. I am trying to build a simple linked list and append some values to it in C.
Below is the list.c file
#include <stdio.h>
#include <stdlib.h>
#include "./list.h"
int main(int argc, char *argv[]) {
int arr[] = {1,2,3,4};
List *list = createList();
int i = 0;
for(i = 0; i < 4; i++) {
appendList(list, arr[i]);
}
return 0;
}
List *createList() {
List *list = malloc(sizeof(List));
if(list == NULL) {
return NULL;
}
list->head = malloc(sizeof(Node));
list->tail = malloc(sizeof(Node));
if(list->head == NULL || list->tail == NULL) {
free(list);
return NULL;
}
list->size = 0;
return list;
}
void appendList(List *list, int num) {
if(list->head->value == 0) {
list->head->value = num;
list->tail->value = num;
return;
}
Node *current = calloc(1, sizeof(Node));
current = list->head;
while(current->next != NULL) {
current = current->next;
}
current->next = calloc(1, sizeof(Node));
if(current->next == NULL) {
free(current->next);
printf("Failed to allocate memory");
exit(1);
}
current->next->value = num;
list->size += 1;
list->tail = current->next;
}
And below is the header file
#ifndef List_h
#define List_h
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} Node;
typedef struct {
Node *head;
Node *tail;
int size;
} List;
List *createList();
void appendList(List *, int num);
Node *removeList(List *);
void printList(List *);
#endif
While running through a debugger, my code seems to be working fine, which makes even less sense.
I assume my issue is in the while loop inside of appendList, where I am trying to access some unallocated piece of memory. Is the issue then with the check I am making, current->next != NULL? Does accessing an unallocated piece of memory necessary return NULL?
Hmm, well my thoughts are that you've created the initial head and tail Nodes and you didn't set its value. Later you use value to determine whether or not you need to add another node or set head and tail to the value passed:
void appendList(List *list, int num) {
if(list->head->value == 0) {
list->head->value = num;
list->tail->value = num;
return;
}
...
The memory returned from malloc will not be necessarily zero, so your algorithm should ensure that all values are set before proceeding.
You then proceed to reach the end of your list:
Node *current = calloc(1, sizeof(Node));
current = list->head;
while(current->next != NULL) {
current = current->next;
}
However, again, while list->head exists, you never set the value of list->head->next! Following an unassigned pointer is not going to end nicely for you in the best of cases.
Consider creating a method to create a new node:
Node* createNode() {
Node* node = malloc(sizeof(Node));
if(node == NULL) {
return NULL;
}
node->value = 0;
node->next = NULL;
return node;
}
Also please note that there's a minor correction to the code here (unrelated to your segmentation fault, but could still create memory leak):
list->head = malloc(sizeof(Node));
list->tail = malloc(sizeof(Node));
if(list->head == NULL || list->tail == NULL) {
free(list);
return NULL;
}
Note that it is possible for list->head to correctly be assigned memory and list->tail to not be correctly assigned memory. In that case, you risk having a memory leak for list->head. Please take the necessary precautions.
Especially in embedded systems, the code compiled for debug mode and the one for release mode can differ. So, for me, there is no surprise that your code works in debug and won't in release.
When creating linked lists using malloc, it is possible that the compiler sets the address of your "struct node * next" element, a non-accessible location in memory. So if you try to access it, you'll get a segfault. (or BAD_EXC in MacOS)
If you suspect that malloc is your problem, try creating a small list with no malloc and see if you have segfault, i.e. use:
struct node myNode;
struct node* pmyNode = &myNode;
In your while loop, I suppose, you are trying to go to the last element of your list. So, instead of:
while(current->next != NULL) {
current = current->next;
}
Try to do this:
last_linked_list_element->next = last_linked_list_element;
current = first_linked_list_element;
while(current != current->next) {
current = current->next;
}
You will break out of the loop when you are at the last element of your list.
Another solution would be to try:
last_linked_list_element->next = NULL;
or
last_linked_list_element->next = &random_identifier;
This will make sure that the pointer locates to an accesible location in memory. Does this solve your problem?
In addition to the previous post, in the following code:
Node *current = calloc(1, sizeof(Node));
current = list->head;
while(current->next != NULL) {
current = current->next;
}
you should to delete the line Node *current = calloc(1, sizeof(Node)); because in this way you allocate memory and than don't use it (subsequently you assign currect pointer to another value).
I keep getting Segmentation Fault (core dumped) run time error and I can't figure out why.
My code:
struct Node
{
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List
{
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr create()
{
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
int insert(ListPtr list, void *obj)
{
NodePtr newObj = malloc(sizeof(struct Node));
//Cast next as a self referencing Node
newObj->next = (NodePtr) newObj->next;
//Point to beginning of list
NodePtr current = list->head;
if(list->head == NULL)
{
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int x = 2;
int *p = &x;
ListPtr thing = create();
insert(thing, p);
return 0;
}
The error is here: list->head->next = newObj after some debugging. I thought I had to allocate memory for list->head->next, but when I added the code in for that it still gave me the same error. Am I casting it wrong or not allocating memory correctly? Any help would be appreciated, thanks!
Just put this together, runs fine.
#include <stdlib.h>
#include <stdio.h>
struct Node {
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List {
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr CreateList() {
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
void Insert(ListPtr list, void *obj) {
// create and initialize new node
NodePtr newObj = malloc(sizeof(struct Node));
newObj->val = obj;
newObj->next = NULL;
//Point to beginning of list
NodePtr curr = list->head;
// Add node to the list
if(curr == NULL) // if no head node, make newObj the head node
{
list->head = newObj;
}
else{ // otherwise traverse the list until you find the last node (the one that points to a null as the next)
while(1) {
if(curr->next != NULL) {
curr = curr -> next;
} else {
curr->next = newObj;
}
list->head = newObj;
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
}
}
}
int main() {
int x = 2;
int *p = &x;
ListPtr thing = CreateList();
Insert(thing, p);
return 0;
}
You check if list->head is NULL and then do some operations with that. Change that to if(list->head != NULL)
{
...
}
At a thought, malloc does not guarantee allocated memory is empty. It's good practice to set all values where they matter after allocation.
list->head is probably not null
also : newObj->next = (NodePtr) newObj->next;
doesn't set to a rational value, it sets to whatever memory was set - were you intending newObj->next = (NodePtr) newObj; ?
list->head should not be referenced if null. list->head->next will only be valid if it's not null.
if you actually want to build a list,
newObj->val = obj;
if (list->head == NULL) { newObj->next = list->head; }
list->head = newObj;
either that or travel down list->head->next chain until next is null, and set that to be newObj->next. If that way then it's possibly a good idea, newObj->next should be set to NULL and not itself.
Might want to figure out how your list will behave - is it circular? does it grow from the head (list->head) or tail (last ->next) ? Do you spot the tail when listObject->next == NULL or when listObject->next == listObject ?
I realize that this answer is mostly stylistic. But I do think that (bad) style and (bad) habits are an (important) part of (bad) programming. Summing it up ...
(in most cases) typedefs are not needed; they just introduce an alias for something that already existed.
[rule of seven] human readers have a limited amount of identifiers ("names") that they can keep track of. This could be 7. Minimising the number of distinct words makes reading easier.
also, the reader has to remember that xPtr and xNode are related (typeof *xPtr === typeof xNode)
when reading source code, keywords and special character tokens (such as operators) don't count as an identifier, since you do not have to remember them. (Syntax-highligting helps, too)
if there is only one way of expressing your program, there is no possibility for errors like iPtr *p; p = (qPtr) malloc (sizeof xNode);
creating yet another struct (+typedefs for it), just to accomodate a root pointer will clobber up your mental namespace even more.
Now a rework of the (intended) code:
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
void *payload;
};
struct node *root=NULL;
void initialize() { /* nothing .... */ }
int insert(struct node **pp, void *pv) {
struct node *p;
p = malloc(sizeof *p);
if (!p) { /* handle error */ return -1; }
p->payload = pv;
p->next = *pp;
*pp = p;
return 1; /* inserted one element */
}
int main(void)
{
int i;
i=666;
/* note: this function call will pass a pointer to a local variable `i`
** to the insert() function, which will remember it.
** This is generally a bad idea, to say the least.
*/
insert( &root, &i);
return 0;
}
I want to read a file and put each words in a linked list. When I read the file, the linked list have the good number of nodes but all the node are equal to the last word.
An example, if my text file is :
Hello good sir
My linked list will look like this :
[sir,sir,sir]
And should be like this :
[Hello, good, sir]
My main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef struct NodeTag {
char *data;
struct NodeTag *next;
} Node;
Node *Node_create();
typedef struct ListTag {
struct NodeTag *first;
} List;
List *List_create();
void List_append(List *list, char *str);
void List_print(List *list);
int main(void) {
char word[100];
FILE *file = fopen("file.txt", "r");
if(file == NULL) {
printf("error in opening file\n");
return 1;
}
List *l = List_create();
while(fscanf(file, "%s", word) == 1){
List_append(l, word);
}
return 0;
}
Here are my functions. I removed the destroy and free functions to make it more clear.
Node *Node_create() {
Node *node = malloc(sizeof(Node));
assert(node != NULL);
node->data = "";
node->next = NULL;
return node;
}
List *List_create() {
List *list = malloc(sizeof(List));
assert(list != NULL);
Node *node = Node_create();
list->first = node;
return list;
}
void List_append(List *list, char *str) {
assert(list != NULL);
assert(str != NULL);
Node *node = list->first;
while (node->next != NULL) {
node = node->next;
}
node->data = str;
node->next = Node_create();
}
void List_print(List *list) {
assert(list != NULL);
printf("[");
Node *node = list->first;
while (node->next != NULL) {
printf("%s", node->data);
node = node->next;
if (node->next != NULL) {
printf(", ");
}
}
printf("]\n");
}
If I do something like this, it will work properly. So I guess I append only the pointer of word so its pointing to the same place again and again ?
List_append(l, "test1");
List_append(l, "test2");
Output :
[test1, test2]
Notice that in main, you have one buffer storing strings:
char word[100];
You pass word as a parameter to your List_append method, during which you write
node->data = str;
This means that all of the nodes are pointing back to the word buffer in main for their string, so all of them will display the same string.
To fix this, you need to duplicate the buffer somewhere. I'd recommend doing something like this:
node->data = strdup(str);
There may be other issues in the code, but this is certainly something that you'll need to fix before you move on. Try updating this and see if it resolves your issue. As #Sean Bright points out, it seems like you're also overwriting the wrong string pointers when you do an append, so you'll probably need to fix that as well.
Hope this helps!
Inside of List_append, you're doing this:
node->data = str;
That saves a pointer to the data that was passed in as str. You call List_append(l, word) in main, meaning you're passing it the same piece of memory every time, so each list member points to the same piece of memory.
You instead need to do this in List_append:
node->data = strdup(str);
This copies the string into a newly allocated buffer. Just be sure to free it when you clean up.
I'm having a problem with inserting a node at the end of a linked list. It's not being executed when the start node is not null and I don't understand the problem. Please help me out here. The function is called second time but is not going to the else block.
typedef struct token_Info
{
int linenumber;
char* token;
char value[200];
struct token_Info* next;
} token_Info;
token_Info *tokenlist;
token_Info* insert_at_end( token_Info *list,char *name)
{
printf("token identified \t");
token_Info *new_node;
token_Info *temp,*start;
start = list ;
char *tempname ;
tempname = name;
new_node= malloc(sizeof(token_Info));
new_node->token = malloc(sizeof(strlen(tempname)+1));
strcpy(new_node->token,tempname);
new_node->next= NULL;
// printf("%d",strlen(tempname));
if(new_node == NULL){
printf("nFailed to Allocate Memory");
}
if(start==NULL)
{
start=new_node;
return start;
}
else
{
printf("anvesh");
temp = start;
while(temp->next != NULL)
{
temp = temp ->next;
}
temp->next = new_node;
return temp;
}
}
tokenlist = insert_at_end(tokenlist,"TK_BEGIN");
tokenlist = insert_at_end(tokenlist,"TK_BEGIN1");
UPDATE
I found two bugs, the first was the head of the list was not being returned when appending the list. The other in the memory allocation for the token string which incorrectly used sizeof.
I repositioned the test of the malloc() return value, and added a second one. I removed several unnecessary temporary variables that were cluttering the code. I added two functions, show_list() and free_list(). Finally, remember that the value string field is still uninitialised.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct token_Info
{
int linenumber;
char* token;
char value[200];
struct token_Info* next;
} token_Info;
token_Info* insert_at_end( token_Info *list, char *name)
{
token_Info *new_node, *temp;
new_node= malloc(sizeof(token_Info));
if(new_node == NULL){ // repositioned
printf("\nFailed to allocate node memory\n");
exit(1); // added
}
new_node->token = malloc(strlen(name)+1); // removed sizeof
if(new_node->token == NULL){ // added
printf("\nFailed to allocate token memory\n");
exit(1);
}
strcpy(new_node->token, name);
new_node->next= NULL;
if(list==NULL)
return new_node;
// append
temp = list;
while(temp->next != NULL)
temp = temp->next;
temp->next = new_node;
return list; // original head
}
void free_list( token_Info *list)
{
token_Info *temp;
while (list) {
temp = list->next;
free(list->token);
free(list);
list = temp;
}
}
void show_list( token_Info *list)
{
printf ("\nCurrent list:\n");
while (list) {
printf ("%s\n", list->token);
list = list->next;
}
}
int main(int argc, char **argv)
{
token_Info *tokenlist = NULL;
tokenlist = insert_at_end(tokenlist, "TK_BEGIN");
show_list(tokenlist);
tokenlist = insert_at_end(tokenlist, "TK_SECOND");
show_list(tokenlist);
tokenlist = insert_at_end(tokenlist, "TK_FINAL");
show_list(tokenlist);
free_list(tokenlist);
return 0;
}
Program output:
Current list:
TK_BEGIN
Current list:
TK_BEGIN
TK_SECOND
Current list:
TK_BEGIN
TK_SECOND
TK_FINAL
The question could also be whether you want tokenlist to be a running end of the list, or remain at the start.
As of right now, your first call:
tokenlist = insert_at_end(tokenlist,"TK_BEGIN");
has tokenlist being the only node in the list.
The second call tokenlist = insert_at_end(tokenlist,"TK_BEGIN1"); returns 'temp' which happens to also be the 'TK_BEGIN' node, ( ie, the first node )
If you want the return value to be the last element, you would return new_node instead of temp. If you want to retain the start, you would return start;
All that said:
The calls to it are not part of any function,
I just ran it with the calls in main and got this output:
int main(void){
tokenlist = insert_at_end(tokenlist,"TK_BEGIN");
tokenlist = insert_at_end(tokenlist,"TK_BEGIN1");
return 0;
}
$> ./a.out
token identified token identified anvesh
I am having trouble with inserting items in linked list. All the elements end up having the same *data content that is inserted in the last. The program compiles successfully. I use gcc and gdb.
I am new to coding so please mention troubles if any that you see in my programming style.
typedef struct Node{
void* data;
struct Node* next;
} *node;
node allocate(){
node current = malloc(sizeof(struct Node));
current->data = NULL;
current->next = NULL;
return current;
}
void insert(node *head, void *data){
// if head has no data then set the data on head and return
if(((*head)->data == NULL)&&((*head)->next == NULL)){
(*head)->data = data;
return;
}
node newHead = allocate();
newHead->data = data;
newHead->next = *head;
*head = newHead;
//printf("Node Data : %d\tNext Node Data : %d",
//*(int *)((*head)->data), *(int *)((*head)->data));
}
int main(int argc, char *argv[]){
node head = allocate();
int count = inputSequence(&head);
int *aod = calloc((size_t) count, sizeof(int));
generateAOD(head, aod);
if(checkJolly(aod, count) == TRUE)
printf("Jolly\n");
else
printf("Not Jolly\n");
return 0;
}
int inputSequence(node *input){
int *num = malloc(sizeof(int));
int count = 0;
while((scanf("%d", num) != EOF)){
insert(input, (void *)num);
count++;
}
traverse(*input, fn);
return count;
}
Your insert logic is non-existant. And you're literally making your life harder by attempting to manage a linked list in the fashion you're using.
The head pointer itself should indicate whether the list is empty. If it is NULL, its empty. If it isn't, there's data. Code the insertion logic accordingly.
And your inputSequence is utterly broken. It only allocates ONE data point, then uses the same data allocation for every insertion. You need one for each insertion.
First, change allocate() to accept the data being inserted. It will make the remaining code less cluttered:
node allocate(void *data)
{
node current = malloc(sizeof(*current));
current->data = data;
current->next = NULL;
return current;
}
Second, insert by allocating a new node as needed.
void insert(node *head, void *data)
{
node p = allocate(data);
p->next = *head;
*head = p;
}
Next, fix inputSequence() to properly allocate memory for each entry:
int inputSequence(node *input)
{
int count = 0;
int num = 0;
// note: check for number of params *successfully* parsed.
// if it isn't 1, its time to leave the loop.
while(scanf("%d", &num) == 1)
{
int *data = malloc(sizeof(num));
*data = num;
insert(input, data);
++count;
}
return count;
}
And lastly, make sure your head pointer is initially NULL in main().
int main(int argc, char *argv[])
{
node head = NULL;
// load linked list
inputSequence(&head);
// ... the rest of your code....;
return 0;
}
With the above, the logical answer of "Is my list empty" is simply if (!head) Further, this makes things like traversal trivial.
void traverse(node ptr, void (*pfn)(void *))
{
while (ptr)
{
pfn(ptr->data);
ptr = ptr->next;
}
}
Freeing the list is equally trivial:
void destroy(node *head)
{
while (*head)
{
node p = *head;
*head = p->next;
free(p->data);
free(p);
}
}
typedef struct Node{
void* data; // Make it as int or any other data type
struct Node* next;
} *node;
In function inputSequence() you are allocating memory for num at the very beginning and making node->data point to this memory each time you are adding a node. Hence data pointer of each node of your linked list points to the same memory location and hence contains the same value.
If you still want to continue with data as a void pointer, allocate num for each iteration of the while loop and pass this to insert function.
while((scanf("%d", num) != EOF)){
num = malloc(sizeof(int);
insert(input, (void *)num);
count++;
}