Hash Tables program crashes - c

I wonder if I'm doing something wrong in my program.
I manage to create a HashTable but when I send it through parameter to my displayingList() function, it crashes.
source.c (contains my functions):
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include "header.h"
#define MAX 255
int countLetters(char myStr[])
{
int myLen = strlen(myStr), i;
int wordLen = 0;
for (i = 0 ; i < myLen; ++i)
{
wordLen += (int)(myStr[i]);
}
return (wordLen%256);
}
void populateList(NodeT *T[255], char myStr[])
{
NodeT *p, *q;
p = (NodeT *)malloc(sizeof(NodeT));
strcpy (p->key, myStr);
int myPos = countLetters(myStr);
if(T[myPos] == NULL)
{
p->next = NULL;
T[myPos] = p;
}
else
{
q = T[myPos];
p->next = q;
T[myPos] = p;
}
}
void displayList(NodeT *T[255])
{
int i;
NodeT *p;
for(i = 0 ; i < 255; ++i)
{
if(T[i] != NULL)
{
printf("Index: %d - Data:", i);
p = T[i];
while(p != 0)
{
printf("%s, ", p->key); // HERE IT CRASHES.
p = p->next;
}
printf("\n");
}
}
}
main.c (contains the int main()):
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(void)
{
NodeT *T[255];
int n, i;
printf("Give no. of elements:");
scanf("%d", &n);
fflush(stdin);
for(i = 0 ; i < n ; ++i)
{
char name[100];
gets(name);
populateList(T, name);
}
displayList(T);
return 0;
}
header.h (and my header):
#ifndef HEADER_H
#define HEADER_H
typedef struct cell
{
char key[100];
struct cell *next;
}NodeT;
int countLetters(char myStr[]);
void populateList(NodeT *T[], char myStr[]);
void displayList(NodeT *T[]);
#endif // HEADER_H
I tried to see what exactly happens with debugger and it seems that when I send T[] list to displayList() function, actually it doesn't have the same structure as it has in main.c.
ISSUE: the insertion works fine, but when I try to display my list (on each index) it crashes.
Any ideas?
Thanks in advance.

The possible solution is to declare the NodeT *T[255] global. However it isn't the best practice at all.

Related

How to merge arrays passed to a function with variable parameters

Ive been researching all day on how to merge arrays, and make functions with variable parameters. Then it got me thinking, 'can't I combine the two?'. I came up with this function. According to my understanding it should work, but I'm getting errors. Can anyone tell me what I'm doing wrong?
#include <stdio.h>
#include <stdarg.h>
char* merge(int num, ...)
{
va_list list;
char arr[9] = {0};
char *temp;
int i;
int j;
int k=0;
va_start(list,num);
for(i=0;i<num;i++)
{
temp = va_arg(list,char[]);
j = 0;
while(temp[j] != 0x00)
{
arr[k] = temp[j];
j++;
}
k++;
}
va_end(list);
return arr;
}
int main()
{
char data_1[] = "my";
char merged_array[9] = "legs";
int n=0;
//merged_array = merge(1, data_1);
while(merged_array == 0x00)
{
printf("%s\n",merged_array[n]);
n++;
}
}
Perhaps this will help get you started:
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
char* merge(char *arr, int num, ...)
{
va_list list;
int i;
va_start(list,num);
for(i=0;i<num;i++)
strcat(arr, va_arg(list,char *));
va_end(list);
return arr;
}
int main()
{
char data_1[] = "my";
char merged_array[9] = "legs";
merge(merged_array, 1, data_1);
printf("%s\n", merged_array);
return(0);
}

How to compile multiple C files in code blocks

So I was originally writing my code in code blocks but when I'd try to compile it would always give me errors saying that it wasn't understanding the references i was making to functions in other files.At which point I starting using atom, but it's come to the point where I need to use he debugging tool in code blocks and I'm still getting the same errors even though my code compiles when I run it through gcc. Can someone help please?? These are the errors I'm getting.
||=== Build: Debug in A2 (compiler: GNU GCC Compiler) ===|
obj\Debug\main.o||In function main':|
main.c|18|undefined reference tocreateMyVector'|
main.c|29|undefined reference to PathInit'|
main.c|30|undefined reference toAllPathsRec'|
main.c|31|undefined reference to `PathPrint'|
||=== Build failed: 4 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vector.h"
#include "path.h"
#define BUFFERSIZE 20
int main()
{
Vector *leVector;
unsigned int size;
char leArray[BUFFERSIZE];
scanf("%u\n",&size);
fgets(leArray,sizeof(leArray),stdin);
leVector = createMyVector(size);
char *element = strtok(leArray, " ");
int i;
for(i=0;i<size;i++){
*(leVector->item + i) = atoi(element);
element = strtok(NULL," ");
}
Path Solution;
PathInit(&Solution,size);
AllPathsRec(0,leVector,&Solution);
PathPrint(&Solution);
return 0;
}
vector.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vector.h"
void vectorRead(Vector * V){
printf("Size of the array is: %d\n",V->size);
int i;
for(i = 0; i < V->size; i++){
if(i == V->size)
printf("%d\n ",*(V->item+i));
else
printf("%d ",*(V->item+i));
}
}
Vector * createMyVector(int size){
Vector * vect = (Vector *)malloc(sizeof(Vector));
vect->size = size;
vect->item = (int *)malloc(sizeof(int)*size);
return vect;
}
path.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vector.h"
#include "path.h"
void PathInit(Path *P, int vsize){
P->size = vsize;
P->item = (int *)malloc(sizeof(int)*vsize);
P->top = -1;
}
int AllPathsRec(int position, Vector *V, Path *Solution){
PathAddEntry(Solution,position);
position += *(V->item + position);
while(Solution->top != V->size -1){
AllPathsRec(position, V, Solution);
}
return 0;
}
int PathAddEntry(Path *P, int entry){
if(P->top >= P->size - 1){
printf("ERROR: STACK OVERFLOW\n");
return 1;
}
P->top++;
*(P->item + P->top) = entry;
return 0;
}
int PathRemoveEntry(Path *P){
if(P->top <= -1){
printf("\nERROR: NO ELEMENT TO REMOVE\n");
return 1;
}
P->top--;
return 0;
}
void PathPrint(Path *P){
printf("Size of the Solution array is: %d\n",P->size);
int i;
for(i = 0;i <= P->top; i++){
if(i == P->top)
printf("%d\n ", *(P->item+i));
else
printf("%d ", *(P->item+i));
}
}
vector.h
#ifndef VECTOR_H
#define VECTOR_H
typedef struct {
int size;
int *item;
}Vector;
Vector * createMyVector(int size);
void vectorRead(Vector * V);
#endif
path.h
#ifndef PATH_H
#define PATH_H
typedef struct{
int size;
int top;
int *item;
}Path;
void PathInit(Path *P, int size);
int AllPathsRec(int position, Vector *V, Path *Solution);
int PathAddEntry(Path *P, int entry);
int PathRemoveEntry(Path *P);
void PathPrint(Path *P);
#endif

Issue with Adjacency List in C

I'm trying to insert nodes in a graph using a adjacency list, but it just crashes when i try to insert this line
criaEstacao("Edgware Road", "Verde, Rosa", 200, 0);
on main(). If there is only one insertion it works.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 20
#define TRUE 1
#define FALSE 0
typedef struct no{
char nome[100];
char linhas[100];
int distancia;
int manutencao;
struct no *prox;
struct no *ant;
} No;
No *LinhaAmarela[max];
No *criaEstacao(char n[100], char l[100], int d, int m){
int i = 0;
No *novo = (No*)malloc(sizeof(No*));
strcpy(novo->nome, n);
strcpy(novo->linhas, l);
novo->distancia = d;
novo->manutencao = m;
novo->prox = NULL;
novo->ant = NULL;
while (LinhaAmarela[i] != NULL && i < max){
i++;
}
LinhaAmarela[i] = novo;
}
int main() {
criaEstacao("Paddington", "Verde, Rosa, Marrom", 200, 0);
criaEstacao("Edgware Road", "Verde, Rosa", 200, 0);
getch();
}
Allocate memory for the struct, not the pointer:
No *novo = malloc(sizeof(No));
of better:
No *novo = malloc(sizeof(*novo));
And always check the return value.

warning: implicit declaration of function TableCreate

I have to build a hash table data structure for this project, which I have done it in other files. For some reason when I compile my program and I get error, which is regarding initialization function (TableCreate();) of hash table. When I remove this part of the code from main function and execute, it works fine but then I get segfault when i try to add something to the hash table.
I believe my hash table code has nothing to do with this errors because my hash table code is based upon examples of Hash table code which was provided to us by our professor
I'm using GCC compiler.
Please help me solve this issue.
Error Message
src/sshell.c: In function âmainâ:
src/sshell.c:34: warning: implicit declaration of function âTableCreateâ
src/sshell.c:34: warning: assignment makes pointer from integer without a cast
sshell.c
#include "parser.h"
#include "shell.h"
#include "hash_table.h"
#include "variables.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(void){
char input[1000], sInput[1000]; // String to get user input
int count=1, len; // num=0;
struct Table *t;
t = TableCreate(); //create the table
int while_track;
FILE *ptr_file;
ptr_file =fopen(".simpleshell_history","a");
fclose(ptr_file);
printf("\nWelcome to the sample shell! You may enter commands here, one\n");
printf("per line. When you're finished, press Ctrl+D on a line by\n");
printf("itself. I understand basic commands and arguments separated by\n");
printf("spaces, redirection with < and >, up to two commands joined\n");
printf("by a pipe, tilde expansion, and background commands with &.\n\n");
printf("\npssh$ ");
while (fgets(input, sizeof(input), stdin)) {
strcpy(sInput, input);
len = strlen(input);
if( input[len-1] == '\n' ){
input[len-1] = '\0';
}
while_track = 1; // used to keep track of loop
while (while_track == 1){
count+=1;
if (strcmp(input, "history")==0){
while_track = History(); // print history function call
}else if (strcmp(input, "!!")==0){
while_track = Previous(input); // execute previous function call
}else if (strncmp(input, "!",1)==0){ // !string and !number sort
if(isdigit(input[1])){
while_track = Number(input);
} else {
while_track = String(input);
}
}else { // if the user entry was not any of specfic comnnad then pass the command to parse to execute
other(input,t);
parse(input);
while_track = 0;
}
}
HistoryFile(sInput); // A function call to recode commands entered by the user into a file
printf("\npssh$ ");
}
return 0;
}
hash_table.c
#include "hash_table.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
void feedData(char * var, char * val, struct Table *t){
//const char * key=0;
printf("\n In FeedData Function\n");
Table_add(t, var, val);
printf("\nInside Feed Function -- Veriable: %s Value: %s\n",var, val);
}
unsigned int hash(const char *x) {
printf("\n In Hash\n");
int i;
unsigned int h = 0U;
printf("\n In Hash - Before for loop\n");
for (i=0; x[i]!='\0'; i++)
printf("\n In Hash - In for loop %d \n", i);
h = h * 65599 + (unsigned char)x[i];
printf("\n In Hash - In for loop - after calculation \n");
unsigned int g;
g = h % 1024;
printf("\n In Hash - In for loop - before return: %u \n",g);
return g;
}
struct Table *Table_create(void) {
printf("\n In Table_create\n");
struct Table *t;
t = (struct Table*)calloc(1, sizeof(struct Table));
return t;
}
void Table_add(struct Table *t, const char *key, char * val){
printf("\n In Table_add\n");
struct Node *p = (struct Node*)malloc(sizeof(struct Node));
int h = hash(key);
printf("\n In Table_add - after hash key\n");
//p->key = *key;
strcpy(p->key,key);
printf("\n In Table_add - after first key\n");
strcpy(p->value,val);
printf("\n In Table_add - after Value\n");
p->next = t->array[h];
printf("\n In Table_add - after p->next\n");
t->array[h] = p;
printf("\n In Table_add - after t->array[h] = p\n");
}
/*
int Table_search(struct Table *t, const char *key, int *value){
struct Node *p;
int h = hash(key); //---------------------------------------------------------------------
for (p = t->array[h]; p != NULL; p = p->next)
if (strcmp(p->key, key) == 0) {
*value = p->value;
return 1;
}
return 0;
}
*/
/*
void Table_free(struct Table *t) {
struct Node *p;
struct Node *nextp;
int b;
for (b = 0; b < BUCKET_COUNT; b++)
for (p = t->array[b]; p != NULL; p = nextp) {
nextp = p->next;
free(p);
}
free(t);
}
*/
hash_table.h file code
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
struct Table *Table_create(void);
void Table_add(struct Table *t, const char *key, char * val);
unsigned int hash(const char *x);
void feedData(char * var, char * val, struct Table *t);
enum {BUCKET_COUNT = 1024};
struct Node {
char key[1000];
char variable[1000];
char value[1000];
struct Node *next;
};
struct Table {
struct Node *array[BUCKET_COUNT];
};
#endif
Warning 1: You are calling TableCreate while your function name is Table_create
Warning 2: After looking at new identifier followed by (, compiler assumes it is a function that takes variable number of arguments and returns int.

Array of Structs strange output?

Can anyone give me some indication as to why array of structs doesn't print out properly ?
I think its something to do with the memory I have allocated to the struct I am unsure !!
Using mac osx mountain lion xcode 4 gcc
Thanks for any help completely stuck!!
(Please have patience I am only a student !)
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
typedef struct{
char* one;
char* two;
} Node;
Node *nodes;
int count = 0;
//-----------------------------------------------------------------------
void add(char *one,char*two){
char x[40];
char y[40];
printf("reached..\n");
strcpy(x,one);
strcpy(y,two);
printf("--> X: %s\n",x);
printf("--> Y: %s\n",y);
Node newNode;
newNode.one = x;
newNode.two = y;
nodes[count]= newNode;
count++;
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void print(){
int x;
for (x = 0; x < 10; x++)
{
printf("%d : (%s, %s) \n",x,nodes[x].one, nodes[x].two);
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void check(char **arg)
{
if(strcmp(*arg, "Add") == 0)
{
add(arg[1],arg[2]);
}else if(strcmp(*arg,"print") == 0)
{
print();
}else{
printf("Error syntax Enter either: \n Add [item1][item2]\n OR \n print\n");
}
}
//-----------------------------------------------------------------------
void readandParseInput(char *line,char **arg)
{
if (fgets (line, 512, stdin)!= NULL) {
char * pch;
pch = strtok (line," \n\t");
int count = 0;
arg[0] = pch;
while (pch != NULL)
{
count++;
pch = strtok (NULL, " \n\t");
arg[count] =pch;
}
}else{
printf("\n");
exit(0);
}
}
//-----------------------------------------------------------------------
int main()
{
int size = 100;
nodes = calloc(size, sizeof(Node));
int i;
for(i = 0;i <100; i++){
printf("%s , %s \n",nodes[i].one,nodes[i].two );
// nodes[i].one = ".";
// nodes[i].two = ".";
}
char line[512]; /* the input line */
char *arg[50]; /* the command line argument */
while (1)
{
readandParseInput(line,arg);
if(arg[0] != NULL){
check(arg);
}
}
return(0);
}
You're keeping pointers to the following automatic variables:
char x[40];
char y[40];
These go out of scope when add() returns, leaving you with dangling pointers.
You either have to turn Node::one and Node::two into arrays, or allocate memory for them on the heap.
In you add() function, you cannot assign one struct to another via an = operator... you would have to copy it...
memcpy( &nodes[count], &newNode )
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *fn;
}NAME;
#define NAME_LEN 20
int main()
{
NAME name;
name.fn = (char *) calloc(NAME_LEN, sizeof(char));
strcpy(name.fn, "Namco");
printf("Name: %s\n", name.fn);
free(name.fn);
return 0;
}
you can't just assign a string like this in c
newNode.one = x;
newNode.two = y;
what is newNode.one referring to???
at Function add
newNode.one = x;
newNode.two = y;
to
newNode.one = strdup(x);
newNode.two = strdup(y);

Resources