Segfaults on commented lines : - c

I'm trying to solve a problem on Codechef. I've posted about this before but am doing in completely differently.
http://www.codechef.com/problems/STEPUP#
The idea of the problem is to determine whether or not the desired situation arises for the given testcase.
A desired situation is when every vertex has a higher indirection than the vertices that are connected to it. Ie. if a->b, F(b) should be > F(a). If this isn't possible for the given setup, output is IMPOSSIBLE. If not, output the minimum value of F(x) for the vertex X with maximum indirection such that it holds for all other vertices.
I haven't tried to print the output for the possible cases yet.
INPUT FORMAT:
First line of input contains a number t, the number of test cases.
Each test case contain starts with two space seperated integers N and M, denoting the number of vertices and the number of edges in the graph respectively.
Each of the following M lines contain two space seperated integers a b denoting an edge from vertex a to vertex b.
There can be multiple edges between two vertices a and b.
For eg.,
2
2 2
1 2
2 1
3 2
1 2
1 3
OUTPUT should be:
IMPOSSIBLE
2
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Node{
int val;
struct Node* next;
};
int indirection[10001];//indirection[a] holds count. What vertex it holds count OF is given by list[a].val;
int main()
{
int testcases, num_vertices, num_edges, a,b,c,d,e;
scanf("%d", &testcases);
while(testcases--)
{
scanf("%d %d",&num_vertices, &num_edges);
struct Node *list[num_vertices];//array of pointers to node
int h;
struct Node * ptr;
for(h=1;h<=num_vertices;h++)
{
list[h]=(struct Node *)malloc(sizeof(struct Node));
list[h]->val=0;
}
memset(indirection,0,10001);
for(e=0;e<10001;e++)
printf("Indirection[e]=%d \n",indirection[e]);
a=1;
while(a<=num_edges)
{
printf("messge printing for the %dth time\n",a);
scanf("%d %d",&b,&c);
printf("Message recd %d \n",indirection[c]);
if(indirection[c]==0)
{
printf("entered case1\n");
list[a]->val=c;
printf("S\n");
//Segfaults here
list[a]->next->val=b;
printf("SS\n");
indirection[a]=1;
ptr=list[a]->next;
printf("SSS \n");
printf("case1\n");
}
else
{ printf("entered case2\n");
indirection[c]++;
//segfaults here if i comment out the previous one
ptr->next->val=b;
printf("case2\n");
ptr=ptr->next;
}
a++;
}
int tra,i;
struct Node *ptr1,*ptrnext;
for(i=1;i<=num_edges;i++)
{
ptr1=list[i];
ptrnext=list[i]->next;
{
if (indirection[ptr1->val]<indirection[ptrnext->val])
{ printf("IMPOSSIBLE");
break;
}
else
{
ptr1=ptrnext;
ptrnext=ptrnext->next;
}
}
}
free(list);
}
}
The 2 statements where I've mentioned a segfault in comments are just before the (I think) questionable statements. If I remove the first, segfault at the second. If I remove both, segfault ANYWAY.
Still trying to solve this problem so I can move forward with the next one. Thanks!

num_vertices treated as if it is 1 based rather than 0 based
struct Node *list[num_vertices];//array of pointers to node
int h;
struct Node * ptr;
// for(h=1;h<=num_vertices;h++)
for(h=0;h<num_vertices;h++)
{
list[h]=(struct Node *)malloc(sizeof(struct Node));
list[h]->val=0;
}
next field is not initialized as answered by Daniel
{
list[h]=(struct Node *)malloc(sizeof(struct Node));
list[h]->val = 0;
list[h]->next = something_maybe_NULL();
}
Suggest simpler malloc() style
list[h] = malloc(sizeof *(list[h]));

Your code segfaults because you create an array of struct Node* and allocate memory for them, but you never set the next pointer of each Node. So each Node's next pointer is just pointing somewhere random in memory and segfaults when you try to access it.
I think your design is just wrong. If you are trying to make a linked list of nodes (as suggested by the presence of a next pointer), you don't need to create an array to hold the nodes at all.

I analyzed all your code and found several problems in it, these problems indicate mainly that you don't understand pointers
Arrays are 0-index based
/* if you declare, struct list[size];
* index goes from 0 ti szie - 1
*/
for (h = 1 ; h <= num_vertices ; h++)
{
You never initialize node->next pointer
/* You should initialize the next node to null. */
list[h]->next = NULL;
Your memset is wrong, sizeof(int) != 1
/* memset(indirection, 0, 10001); wrong */
memset(indirection, 0, 10001 * sizeof(int));
You don't check for overflow when accessing the indirection array
/* this is very unsafe, you don't check c */
printf("Message recd %d \n", indirection[c]);
You dereference node->next without checking for NULL
/* don't dereference list[a]->next without checking .
* list[a]->next->val (wrong)
*/
next = list[a]->next;
if (next != NULL)
next->val = b;
You free list, it is an array not a pointer so you can't call free on it, however, you should free its elements, since they are pointers to valid malloced memory
for (i = 0 ; i < num_vertices ; i++)
free(list[i]);
Here is a version of your code with this issues fixed, I don't know if your algorithm works, but the code has at least 6 fewer errors.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/* no need for typedef, since you declare as struct Node */
struct Node
{
int val;
struct Node* next;
};
int indirection[10001];//indirection[a] holds count. What vertex it holds count OF is given by list[a].val;
int main()
{
int testcases, num_vertices, num_edges, a, b, c;
printf("input testcase: ");
scanf("%d", &testcases);
while (testcases--)
{
printf("input testcase num_vertices and num_edges: ");
scanf("%d %d",&num_vertices, &num_edges);
int h;
struct Node *list[num_vertices]; // array of pointers to node
struct Node *ptr;
/* struct list[size];
* index goes from 0 ti szie - 1
*/
for (h = 0 ; h < num_vertices ; h++)
{
/* If this is plain C you don't need the cast (struct Node *) */
list[h] = malloc(sizeof(struct Node));
list[h]->val = 0;
/* You should initialize the next node to null. */
list[h]->next = NULL;
}
/* memset(indirection, 0, 10001); wrong */
memset(indirection, 0, 10001 * sizeof(int));
/* What, you dont believe all values are 0? */
/* for(e = 0 ; e < 10001 ; e++)
printf("Indirection[e] = %d\n",indirection[e]); */
/* arrays go from 0 ti size - 1 */
a = 0;
while (a < num_edges)
{
printf("messge printing for the %dth time\n", a);
printf("input b and c: ");
scanf("%d %d", &b, &c);
if (c < 10001)
{
/* this is very unsafe, you don't check c */
printf("Message recd %d \n", indirection[c]);
if (indirection[c]==0)
{
struct Node *next;
printf("entered case1\n");
list[a]->val = c;
printf("S\n");
// Segfaults here
/* don't dereference list[a]->next without checking . */
next = list[a]->next;
if (next != NULL)
next->val = b;
printf("SS\n");
indirection[a] = 1;
ptr = list[a]->next;
printf("SSS \n");
printf("case1\n");
}
else
{
printf("entered case2\n");
indirection[c]++;
//segfaults here if i comment out the previous one
ptr->next->val=b;
printf("case2\n");
ptr=ptr->next;
}
a++;
}
}
int i;
struct Node *ptr1, *ptrnext;
for(i = 0 ; i < num_edges ; i++) /* arrays go from 0 ti size - 1 */
{
ptr1 = list[i];
if (ptr1 != NULL)
ptrnext = ptr1->next;
if ((ptr1 != NULL) && (ptrnext != NULL))
{
if (indirection[ptr1->val] < indirection[ptrnext->val])
{
printf("IMPOSSIBLE");
break;
}
else
{
ptr1 = ptrnext;
ptrnext = ptrnext->next;
}
}
}
for (i = 0 ; i < num_vertices ; i++)
free(list[i]);
}
return 0;
}

in your code
list[a]->next->val=b;
list[a]->next maybe NULL. IMO, it's better to put a NULL check before dereferencing.
Same goes for ptr->next in
ptr->next->val=b;
Nevertheless, you need to allocate memory to next before using it. Otherwise, it will point to some
unknown memory location.
Also, why not start the loop from 0 in
for(h=1;h<=num_vertices;h++)
Sidenote: Please do not cast the return value of malloc().

Related

Linked list without struct, but using only arrays

#include <stdio.h>
int main()
{
int n, i;
int head = 0;
printf("No of Students:\n");
scanf("%d", &n);
int data[n];
int address_of_data[n];
int *next;
printf("Enter Marks:\n");
for (i = 0; i < n; i++)
{
scanf("%d", &data[i]);
}
for (i = 0; i < n; i++)
{
if (data[head] != -1)
{
address_of_data[head] = &data[i];
}
else
{
break;
}
head++;
}
next = address_of_data[0];
for (i = 0; i < n; i++)
{
printf("%d ", *(next + i));
}
return 0;
}
In the above code, I used pointers to print the data values. Using two arrays, one for the data and another for the address of the data. But I don't how to actually implement a linked List out of this, I am really confused, can anyone tell how to implement a Linked-List without using structures.
The key advantage of a linked list is that when you insert or append an element, you can store that element anywhere in memory. Other elements in the list can point to it, and if you iterate over the list, you jump back and forth anywhere in memory following the pointers down the chain formed by the elements, until you reach the tail, which has a null pointer because it is the last element.
Implementing a linked list 'using only arrays' does not really make much sense. Even if you could, why would you want to? Arrays are great because you can index directly into them in constant time - you can't do this with linked lists, you can only iterate over them. But arrays have their drawbacks too - they are fixed size, and when they fill up, they fill up! Most shared library lists like the ArrayList in Java or the vector class in C++ store the underlying data in a fixed size array, and then if you insert too many items for that array, they create a new, larger array behind the scenes and copy the elements across for you. There really is no magic solution for when you run out of room in your array.
So with that being said, why would you implement a linked list using only arrays? You remove their only advantage - that you can append arbitrarily without costly reallocations. I'm not even sure if it's a well defined question. Perhaps if you're really desperate, you can create one large array and treat it like your own virtual memory, allocating and freeing slots in it, and then treat a two element array as an entry (entry[0] = data, entry[1] = 'address' of next, i.e. an index into your large array). But this smacks of terrible code and is really missing the point of linked lists.
Here is a complete example of a simple linked list - for more ease in pure C. Note the "next" member in the structure - this is a pointer to the successor in the list.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MY_DATA {
int number;
char info[30];
struct MY_DATA *next;
};
#define MAX_ELEMS 5
int main(int argc, char **argv)
{
struct MY_DATA *root = NULL; /* Root of list */
struct MY_DATA *prev = NULL; /* Previously created element */
for(int i = 0; i < (MAX_ELEMS); i++)
{
/* Allocate memory ... */
struct MY_DATA *new_data = (struct MY_DATA *)malloc(sizeof(MY_DATA));
/* ...and inialize new data set */
memset(new_data, 0x00, sizeof(MY_DATA));
new_data->number = i * i;
sprintf((char *)&(new_data->info), "This is data record %d", i);
if (root == NULL)
{
root = prev = new_data; /* Remember the first element */
}
else
{
prev->next = new_data; /* The previous element has now a successor */
prev = new_data; /* Remember this for next iteration */
}
}
struct MY_DATA *current = root; /* Get the 1st element in the list */
struct MY_DATA *temp = NULL; /* Just for clean up stuff */
for(int i = 0; i < (MAX_ELEMS); i++)
{
/* Display data */
printf("Data set #%d: %s\n", current->number, current->info);
temp = current; /* This becomes deleted */
current = current->next; /* Set current pointer to successor of current element */
free(temp);
}
return 0;
}
Another exampe - accessing an array with indexes or pointers:
#include <stdio.h>
#define MAX_ELEMS 5
int my_array[MAX_ELEMS] = { 5, 18, 42, 31, 10 };
int main(int argc, char **argv)
{
int *current = (int *)my_array; /* Get the 1st element in the list */
for(int i = 0; i < (MAX_ELEMS); i++)
{
/* Using array index */
printf("Data set #%d \n" \
" Indexed access: %d\n", i, my_array[i]);
/* Using the pointer*/
printf(" Pointer access: %d\n", *current++);
}
return 0;
}

free the memory in C

The result of code 1 is still 10 after you free pointer p and p is not NULL.
the inputs of code 2 are 5 (length) and 1 2 3 4 5 for the value of each node, but the output is nothing under the condition that all the following nodes are not NULL.
My question is that based on the logic of code 1, shouldn't all the values of nodes be printed because they are not NULL?
Can anyone explain to me? Thank you so much!
code 1:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
if (p != NULL) {
printf("%d\n", *p);
}
return 0;
}
code 2:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
struct Node *next;
int value;
} Node, *list;
list create_Node() {
list head = (list)malloc(sizeof(Node));
if (!head)
exit(-1);
list tail = head;
int len;
int val;
printf("Please enter the length of the list:\n ");
scanf("%d", &len);
for (int i = 0; i < len; i++) {
list new = (list)malloc(sizeof(Node));
if (!new)
exit(-1);
printf("Please enter the value of the node:\n ");
scanf(" %d", &val);
new->value = val;
tail->next = new;
tail = new;
}
return head;
}
int delete_List(list l) {
if (l == NULL) {
printf("List is empty!");
exit(-1);
}
list temp;
while (l) {
temp = l->next;
free(l);
l = temp;
}
return 1;
}
int main() {
Node *n = create_Node();
n = n->next;
delete_List(n);
while (n->next != NULL) {
printf("%d\n", n->value);
n = n->next;
}
return 0;
}
...based on the logic of code 1...
Code 1 accesses freed memory (a so-called dangling pointer), which is undefined behavior. Anything can happen, including, but not limited to, your program crashing, the last value being returned (= the behavior you observed) or the program doing something completely unexpected.
Thus, you cannot infer anything from "the logic of code 1".
having
int main(){
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
if(p!=NULL)
{
printf("%d\n",*p);
}
return 0;
}
My question is that based on the logic of code 1, shouldn't all the values of nodes be printed because they are not NULL??
Except in the case there are no more memory the malloc will works and return a non null value, after the free the value of p is unchanged and still non null so the code try to read in the free memory and this is an undefined behavior
There are better way to ( try to) print a random value :-)
in code 2 this is the same, you access to free memory, both in the test of the while and in the printf and the value to assign n

A pointer points to a NULL pointer

code from cs50 harvard course dealing with linked list:
---The problem I do not understand is that when node *ptr points to numbers, which is a null pointer, how can the for loop: (node *ptr = numbers; ptr != NULL) run at all since *numbers = NULL?---
full version of the codes can be found at: https://cdn.cs50.net/2017/fall/lectures/5/src5/list2.c
#include <cs50.h>
#include <stdio.h>
typedef struct node
{
int number;
struct node *next;
}
node;
int main(void)
{
// Memory for numbers
node *numbers = NULL;
// Prompt for numbers (until EOF)
while (true)
{
// Prompt for number
int number = get_int("number: ");
// Check for EOF
if (number == INT_MAX)
{
break;
}
// Check whether number is already in list
bool found = false;
for (node *ptr = numbers; ptr != NULL; ptr = ptr->next)
{
if (ptr->number == number)
{
found = true;
break;
}
}
The loop is to check for prior existence in the list actively being built. If not there (found was never set true), the remaining inconveniently omitted code adds it to the list.
On initial run, the numbers linked list head pointer is null, signifying an empty list. That doesn't change the algorithm of search + if-not-found-insert whatsoever. It just means the loop is never entered because the bail-case is immediately true. in other words, with numbers being NULL
for (node *ptr = numbers; ptr != NULL; ptr = ptr->next)
the condition to continue, ptr != NULL is already false, so the body of the for-loop is simply skipped. That leads to the remainder of the code you didn't post, which does the actual insertion. After that insertion, the list now has something, and the next iteration of the outer-while loop will eventually scan the list again after the next prospect value is read. This continues until the outer-while condition is no longer satisfied.
A Different Approach
I have never been fond of the cs50 development strategy, and Harvard's technique for teaching C to entry-level CS students. The cs50 header and lib has caused more transitional confusion to real-world software engineering than one can fathom. Below is an alternative for reading a linked list of values, keeping only unique entries. It may look like a lot, but half of this is inline comments describing what is going on. Some of it will seem trivial, but the search-and-insert methodology is what you should be focusing on. It uses a strategy of pointer-to-pointer that you're likely not familiar with, and this is a good exposure.
Enjoy.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int value;
struct node *next;
};
int main()
{
struct node *numbers = NULL;
int value = 0;
// retrieve list input. stop when we hit
// - anything that doesn't parse as an integer
// - a value less than zero
// - EOF
while (scanf("%d", &value) == 1 && value >= 0)
{
// finds the address-of (not the address-in) the first
// pointer whose node has a value matching ours, or the
// last pointer in the list (which points to NULL).
//
// note the "last" pointer will be the head pointer if
// the list is empty.
struct node **pp = &numbers;
while (*pp && (*pp)->value != value)
pp = &(*pp)->next;
// if we didn't find our value, `pp` holds the address of
// the last pointer in the list. Again, not a pointer to the
// last "node" in the list; rather the last actual "pointer"
// in the list. Think of it as the "next" member of last node,
// and in the case of an empty list, it will be the address of
// the head pointer. *That* is where we will be hanging our
// new node, and since we already know where it goes, there is
// no need to rescan the list again.
if (!*pp)
{
*pp = malloc(sizeof **pp);
if (!*pp)
{
perror("Failed to allocate new node");
exit(EXIT_FAILURE);
}
(*pp)->value = value;
(*pp)->next = NULL;
}
}
// display entire list, single line
for (struct node const *p = numbers; p; p = p->next)
printf("%d ", p->value);
fputc('\n', stdout);
// free the list
while (numbers)
{
struct node *tmp = numbers;
numbers = numbers->next;
free(tmp);
}
return EXIT_SUCCESS;
}
This approach is especially handy when building sorted lists, as it can be altered with just a few changes to do so.
If you examine rest of the code which is also within the while loop, you can see alteration of numbers on the shared link.
if (!found)
{
// Allocate space for number
node *n = malloc(sizeof(node));
if (!n)
{
return 1;
}
// Add number to list
n->number = number;
n->next = NULL;
if (numbers)
{
for (node *ptr = numbers; ptr != NULL; ptr = ptr->next)
{
if (!ptr->next)
{
ptr->next = n;
break;
}
}
}
else
{
numbers = n;
}
}
Besides, it doesn't hit body of the for loop at first, so your thinking is correct.

Inserting into hash table

I am trying to insert an integer into a hash table. To do this, I'm creating an array of node*'s and I'm trying to make assignments like listarray[i]->data=5 possible. However, I'm still very confused with pointers and I'm crashing at the line with the comment '//crashes here' and I don't understand why. Was my initialization in main() invalid?
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node * next;
} node;
//------------------------------------------------------------------------------
void insert (node **listarray, int size)
{
node *temp;
int value = 11; //just some random value for now, eventually will be scanned in
int index = value % size; // 11 modulo 8 yields 3
printf ("index is %d\n", index); //prints 3 fine
if (listarray[index] == NULL)
{
printf("listarray[%d] is NULL",index); //prints because of loop in main
listarray[index]->data = value; //crashes here
printf("listarray[%d] is now %d",index,listarray[index]->data); //never prints
listarray[index]->next = NULL;
}
else
{
temp->next = listarray[index];
listarray[index] = temp;
listarray[index]->data = value;
}
}//end insert()
//------------------------------------------------------------------------------
int main()
{
int size = 8,i; //set default to 8
node * head=NULL; //head of the list
node **listarray = malloc (sizeof (node*) * size); //declare an array of Node *
//do i need double pointers here?
for (i = 0; i < size; i++) //malloc each array position
{
listarray[i] = malloc (sizeof (node) * size);
listarray[i] = NULL; //satisfies the first condition in insert();
}
insert(*&listarray,size);
}
output:
index is 3
listarray[3] is NULL
(crash)
desired output:
index is 3
listarray[3] is NULL
listarray[3] is now 11
There are various issues here:
If you have a hash table of a certain size, then the hash code must map to a value between 0 and size - 1. Your default size is 8, but your hash code is x % 13, which means that your index might be out of bounds.
Your insert function should also pass the item to insert (unless that's the parameter called size, in which case it is severely misnamed).
if (listarray[index] == NULL) {
listarray[index]->data = value; //crashes here
listarray[index]->next = NULL;
}
It's no wonder that it crashes: When the node is NULL, you cannot dereference it with either * or ->. You should allocate new memory here.
And you shouldn't allocate memory here:
for (i = 0; i < size; i++) //malloc each array position
{
listarray[i] = malloc (sizeof (node) * size);
listarray[i] = NULL; //satisfies the first condition in insert();
}
Allocating memory and then resetting it to NULL is nonsense. NULL is a special value that means that no memory is at the pointed-to location. Just set all nodes to NULL, which means that the hash table starts out without any nodes. Allocate when you need a node at a certain position.
In the else clause, you write:
else
{
temp->next = listarray[index];
listarray[index] = temp;
listarray[index]->data = value;
}
but temp hasn't been allocated, but you dereference it. That's just as bad as dereferencing ´NULL`.
Your hash table also needs a means to handle collisions. It looks as if at every index in the hash table, there is a linked list. That's a good way to deal with it, but you haven't implemented it properly.
You seem to have problems to understand pointers. Perhaps you should start with a simpler data structure like a linked list, just to practice? When you have gotten a firm grasp of that, you can use what you've learned to implement your hash table.

Symbol table implementation using hash table in C

I am trying to implement a simple symbol table that stores the strings in a hash table according to their hash values. The hash table in my program is an array of pointers to linked lists. we have 6 linked lists corresponding to each hash value.
The problem is that though the program runs, it replaces the old strings with the new string in each iteration.
my code is..
struct node{
char *string;
struct node *next;
};
struct node *hashtable[6];
int calchash(char *arr);
main()
{
char *line, a='n';
int val, i;
do{
printf("Enter string:\n");
scanf("%s", line);
struct node *current;
struct node *q= (struct node*)malloc(sizeof(struct node));
q->string = line;
q->next = NULL;
val= calchash(line);
if(hashtable[val] == NULL)
{
hashtable[val] = q;
current =q;}
else{
current->next = q;
current = q;
}
printf("Node created\n");
for(i=0; i<6; i++)
{ printf("Hash value %d :\n", i);
if(hashtable[i]==NULL)
{printf("No STRINGS!\n\n");}
else
{struct node *t = hashtable[i];
while(t != NULL)
{printf("%s \n", t->string);
t = t->next;}
printf("\n\n");
}
}
printf("CONTINUE(y/n):\n");
scanf(" %c", &a);
}while(a!='n');
}
int calchash(char *arr)
{int i=0, ascii;
int sum=0;
while(arr[i] != '\0')
{ascii = arr[i];
if(ascii>=48 && ascii<=57)
{
sum+= 2*ascii;}
else
{sum=sum+ ascii;}
i++;
}
return ((sum*17+5)%6);
}
And the output is:
Enter string:
az9
Node created
Hash value 0 :
No STRINGS!
Hash value 1 :
No STRINGS!
Hash value 2 :
az9
Hash value 3 :
No STRINGS!
Hash value 4 :
No STRINGS!
Hash value 5 :
No STRINGS!
CONTINUE(y/n):
y
Enter string:
Az9
Node created
Hash value 0 :
No STRINGS!
Hash value 1 :
No STRINGS!
Hash value 2 :
Az9
Hash value 3 :
No STRINGS!
Hash value 4 :
Az9
Hash value 5 :
No STRINGS!
CONTINUE(y/n):
n
Can someone please tell me what changes are needed so as to retain the previous az9 string under hash value 2???
if(hashtable[val] == NULL) {
hashtable[val] = q;
current =q;
} else {
current->next = q;
current = q;
}
should be replaced with:
q->next = hashtable[val];
hashtable[val] = q;
// no need for current
Also, writing through any uninitialised pointer is UB, please allocate sufficient space first. Anything might happen...
How does this not crash immediately? Neither line nor hashtable are initialized.
You will need to make a copy of the string to go into each hash node, probably with strdup. Currently, all of the nodes point to the same string buffer as line, so when you read a new string into line, all of the nodes will see it. This is why you must duplicate the string for each node. I wonder where the buffer ended up though, since you never initialized line...
Also, what is current? It is local to the loop, and appears unnecessary. You should just chain new nodes onto the head of the bucket, so you don't need to check if the bucket is empty.
The insert also does not check if the string is already present, so you will insert duplicates.

Resources