Why Does One C Hash Table Implementation Fail While the Other Succeeds?

  • Thread starter Thread starter zorro
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around the differences between two implementations of a hash table in C, specifically focusing on the data types used for storing words in the hash table. Participants explore the implications of using pointers versus fixed-size arrays for character storage within the hash table structure.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • Some participants explain that using "char *cword" allows for dynamic memory allocation, meaning it can point to different character arrays, while "char cword[20]" creates a fixed-size array that cannot be reassigned.
  • Others note that the size of "cword" differs based on its declaration, with "char *cword" returning the size of a pointer and "char cword[20]" returning the size of the array itself.
  • One participant emphasizes the need for memory management with pointers, highlighting the risk of memory leaks if allocated memory is not freed properly.
  • Another participant suggests that fixed-size arrays are less flexible but simpler to manage, as they do not require manual memory management.
  • There is mention of using typedefs for structures in C to simplify declarations, but this suggestion remains unaddressed in terms of consensus.

Areas of Agreement / Disagreement

Participants express differing views on the advantages and disadvantages of using pointers versus fixed-size arrays in the context of hash table implementations. No consensus is reached on which approach is superior, as both have their respective merits and drawbacks.

Contextual Notes

Limitations include the potential for memory management issues with pointers and the fixed size constraint of arrays, which may not accommodate longer strings. The discussion does not resolve these limitations.

Who May Find This Useful

Readers interested in C programming, data structures, and memory management may find this discussion relevant.

zorro
Messages
1,378
Reaction score
0
Can some one explain me the difference between the following two pieces of code ?
First one doesn't work. I debugged it and made it to work but I am unable to understand how.
The lines with changes have been made red bold.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 100

int hash_func(char k[]);
void hash(int key,char k1[],char k2[]);
char *search(int key,char k[]);struct hash_table{

[B]	char *cword;
	char *mword;[/B]
	struct hash_table *next;
	
};

struct hash_table *arr[SIZE];

int main() {
	char k1[100];
	char k2[100];
	char buf[200];
	char test[100];
	char *word;
	int key;
	int i;
	int choice1;
	int choice2;
	FILE *fp1;
	FILE *fp2;

	fp1=fopen("spell.txt","r");
	if(fp1==0){
		printf("Could not open dictionary file");
		exit(0);
	}
	for(i=0;i<SIZE;i++){
		arr[i]=NULL;
	}
	
			while(fscanf(fp1,"%s",k1)!=EOF){
                		fscanf(fp1,"%s",k2);
               			key=hash_func(k1);
	            		hash(key,k1,k2);
	            	
				printf("%d %s %s\n",key,arr[key]->cword,arr[key]->mword);
        		}
			printf("%s\n",arr[56]->mword);
			printf("Enter 0 for auto spell check and 1 for manual check\n");
			scanf("%d",&choice1);
			for(i=0;i<100;i++){	
				if(arr[i]!=NULL)
				printf("%d >>%s\n",i,arr[i]->cword);
			}
			while(fscanf(fp2,"%s",k1)!=EOF){
				key=hash_func(k1);
				word=search(key,k1);
				if(choice1==0){
					//fprintf(fp2,"%s",k2);
					printf("--%s--",word);
				}
				else{
					printf("Misspelled Word : %s  Correct Word : %s\n",k1,k2);
					printf("Enter 0 to modify the word in file\n");
					scanf("%d",&choice2);
					if(choice2==0)
						fprintf(fp2,"%s",k2);
				}				
							
			}
		
	
}

int hash_func(char k[]){

	int n;
	int sum=0;
	n=strlen(k);
	while(n--){
		sum=sum+*k++;
	}
	printf("key %d\n",sum%100);
	return sum%100;
}

void hash(int key,char k1[],char k2[]){

	struct hash_table *temp,*new;
	temp=arr[key];
		
	if(temp==NULL){
		arr[key]=(struct hash_table *)malloc(sizeof(struct hash_table));
		
		[B]arr[key]->cword=k2;		
		arr[key]->mword=k1;[/B]
		arr[key]->next=NULL;
		
	}

	else{
		while(temp->next!=NULL)
			temp=temp->next;
		new=(struct hash_table *)malloc(sizeof(struct hash_table));
        	[B]new->mword=k1;
       	 	new->cword=k2;[/B]
        	new->next=NULL;
		temp->next=new;
	}
}
		char * search(int key,char k[]){

	struct hash_table *temp;
	if(arr[key]==NULL){
		printf("*1*");
		return k;
	}

	else{
		temp=arr[key];
		while(temp->next!=NULL){
			if(strcmp(k,temp->mword)==0){
				printf("*2*");
				return temp->cword;
			}
			temp=temp->next;
		}
	}
}
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int hash_func(char k[]);
void hash(int key,char k1[],char k2[]);
char *search(int key,char k[]);struct hash_table{

[B]	char cword[20];
	char mword[20];[/B]
	struct hash_table *next;
	
};

struct hash_table *arr[100];

int main() {
	char k1[100];
	char k2[100];
	char buf[200];
	char test[100];
	char *word;
	int key;
	int i;
	int choice1;
	int choice2;
	FILE *fp1;
	FILE *fp2;

	fp1=fopen("spell.txt","r");
	if(fp1==0){
		printf("Could not open dictionary file");
		exit(0);
	}
	for(i=0;i<100;i++){
		arr[i]=NULL;
	}
	
			while(fscanf(fp1,"%s",k1)!=EOF){
                		fscanf(fp1,"%s",k2);
               			key=hash_func(k1);
	            		hash(key,k1,k2);
	            	
				printf("%d %s %s\n",key,arr[key]->cword,arr[key]->mword);
		         
        		}
			printf("%s\n",arr[56]->mword);
			printf("Enter 0 for auto spell check and 1 for manual check\n");
			scanf("%d",&choice1);
			for(i=0;i<100;i++){	
				if(arr[i]!=NULL)
				printf("%d >>%s\n",i,arr[i]->cword);
			}
			while(fscanf(fp2,"%s",k1)!=EOF){
				key=hash_func(k1);
				word=search(key,k1);
				if(choice1==0){
					//fprintf(fp2,"%s",k2);
					printf("--%s--",word);
				}
				else{
					printf("Misspelled Word : %s  Correct Word : %s\n",k1,k2);
					printf("Enter 0 to modify the word in file\n");
					scanf("%d",&choice2);
					if(choice2==0)
						fprintf(fp2,"%s",k2);
				}				
							
			}
		
	
}

int hash_func(char k[]){

	int n;
	int sum=0;
	n=strlen(k);
	while(n--){
		sum=sum+*k++;
	}
	printf("key %d\n",sum%100);
	return sum%100;
}

void hash(int key,char k1[],char k2[]){

	struct hash_table *temp,*new;
	temp=arr[key];
	
	if(temp==NULL){
		arr[key]=(struct hash_table *)(malloc(sizeof(struct hash_table)));
	[B]	strcpy(arr[key]->cword,k2);		
		strcpy(arr[key]->mword,k1);[/B]
		arr[key]->next=NULL;
		
	}

	else{
		while(temp->next!=NULL)
			temp=temp->next;
		new=(struct hash_table *)malloc(sizeof(struct hash_table));
   [B]     	strcpy(new->mword,k1);
       	 	strcpy(new->cword,k2);[/B]
        	new->next=NULL;
		temp->next=new;
	}
}
		char * search(int key,char k[]){

	struct hash_table *temp;
	if(arr[key]==NULL){
		printf("*1*");
		return k;
	}

	else{
		temp=arr[key];
		while(temp->next!=NULL){
			if(strcmp(k,temp->mword)==0){
				printf("*2*");
				return temp->cword;
			}
			temp=temp->next;
		}
	}
}
 
Technology news on Phys.org
"char *cword" means cword is a pointer to a character (which may be an array of characters). 'cword' may be assigned to so that you can point to different characters. Just defining 'cword' did not create a character or array of characters.

"char cword[200]" means cword is a pointer to an array of 200 characters that has been allocated by the compiler. You cannot assign a new value to 'cword' to point to a different array of characters.

I suggest getting a good book on C -- but I can't recommend any because I taught myself almost two decades ago.
 
As posted, "char * cword" declares cword to be a pointer to a single character, which may be the first character of an array of characters. Somewhat different than what was posted, "char cword[20]" declares cword to be an array of 20 characters, and although it can be used similar to a pointer, it's not a pointer. If you examine the size, such as sizeof(cword), in the first case you'll get the size of a pointer, probably 4 or 8 bytes depending if the computer is running in 32 bit or 64 bit mode. In the second case, sizeof(cword) will return the size of the array, which is 20.

In the first case, you'll need to assign a pointer to cword each time you declare an instance of the hash_table structure. This can be an array name, as in your first example, or you can allocate (malloc) an array of characters (you'll need to free them as well).

Also you can use typedefs for structures in C:

Code:
typedef struct_hash_table{ /* prefix of _ commonly used for struct name */
    char cword[20];
    char mword[20];
    struct _hash_table *next;
}hash_table, *phash_table; /* typedefs for hash table and ptr to hash table */

/* ... */

phash_table arr[100] /* declare an array of 100 pointers to hash_table */
 
Last edited:
Or maybe think of it like this

Code:
char *cword;
requires you to create and maintain memory storage for this variable. It is super flexible. You can use it to refeence almost any size string object. But it has a lot more "programmer responsibility" overhead. If you allocate memory [ malloc() or strdup() ] to it then you have to clean up [ free() ] later. If you "forget" to clean up then you can literally leak memory out of the program into a place where you cannot use it anymore.. If you merely decide to "aim it" at an existing place in memory, that place cannot change.

Code:
char cword[20];
Is less flexible. You have basically one option: [ strcpy() or memcpy() ] to load data into it. It will last, it does not need tending. It cannot handle anything larger than 19 character strings -- C requires an extra trailing nul (ASCII 0 character on every string. If you copy 2 characters into it, it still uses up 20 character total.

So the latter choice will work well for any language that has no word longer than 20 characters. The former choice is much better for huge dictionaries where consuming memory space wisely is important.
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
Replies
6
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 3 ·
Replies
3
Views
6K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 12 ·
Replies
12
Views
3K