0

This is a lot of code but I'm at ends here trying to figure out why its not working.

This is the code I'm running:

struct dict {
  struct word **tbl;
  int (*hash_fcn)(struct word*);
  void (*add_fcn)(struct word*);
  void (*remove_fcn)(struct word*);
  void (*toString_fcn)(struct word*);
};

struct word {
  char *s;
  struct word *next;
};

this is part of the main function:

  hashtbl=malloc(sizeof(struct dict));
  //hashtbl->tbl=malloc(sizeof(struct word*)*256);
  int i;
  for(i=0;i<256;i++)
  {
    hashtbl->tbl[i] = malloc(sizeof(struct word));
    hashtbl->tbl[i] = NULL;
    //hashtbl->tbl[i]=NULL;
  }
  hashtbl->add_fcn=&add_word;
  hashtbl->remove_fcn=&remove_word;
  hashtbl->hash_fcn=&hash_function;
  hashtbl->toString_fcn=&toString;

  FILE *p;
  p = fopen("a.txt", "r");
  if(p == NULL) { printf("ERROR!\n"); return 0; }
  char line[MAXBYTES];
  while(fgets(line, MAXBYTES, p))
  {
      char *token = strtok(line, " ");
      while(token != NULL)
     {
        struct word *words = malloc(sizeof(struct word));
        words->s = token;
        words->next=NULL;
        trim(words);
        hashtbl->add_fcn(words);
        token = strtok(NULL, " ");

        printf("....\n");
        hashtbl->toString_fcn(NULL);
        printf("....\n\n");

      }
      free(token);
  }

Here are two functions used (to String just prints it out)

void add_word(struct word *insert)
{
  if(strcmp(insert->s, "\n") == 0) {return;}

  int hash = hashtbl->hash_fcn(insert);

  if(hash==0) { return; }
  struct word *word = hashtbl->tbl[hash];
  if(word==NULL)
  {
    struct word *newword = malloc(sizeof(struct word));
    newword->s=insert->s;
    newword->next=NULL;
    hashtbl->tbl[hash]=newword;

    printf("() %d %s \n", hash, hashtbl->tbl[hash]->s);
  }
  else
  {
    struct word *tp = word;
    while(word->next != NULL)
      word=word->next;
    struct word *newword = malloc(sizeof(struct word));
    newword->s=insert->s;
    newword->next=NULL;
    word->next=newword;
    hashtbl->tbl[hash]=tp;
  }
}

int hash_function(struct word *string)
{
  char *firstletter = string->s;
  char c = *firstletter;
  int ascii = (int)c;
  return ascii;
}

a.txt is

cat
dog
mouse

and it prints out the following:

() 99 cat 
....
99 : cat 
....

() 100 dog 
....
99 : dog 
100 : dog 
....

() 109 mouse 
....
99 : mouse 
100 : mouse 
109 : mouse 
....

it should be printing out

99:cat 
100:dog
109:mouse

thanks

3
  • possible duplicate of c double pointer array --- in the light of "is not working" being the only problem description, I'm tempted to say that the OP should just communicate more in his previous question to get the problem solved. Commented Nov 14, 2011 at 4:10
  • Did you run a debugger on that program ? Commented Nov 14, 2011 at 4:10
  • Hint: Review the documentation for strtok() and make sure you understand exactly who owns the memory pointed to by the return value, and how you are currently using that value. Commented Nov 14, 2011 at 4:15

1 Answer 1

2

You have many problems here.

First:

hashtbl=malloc(sizeof(struct dict));
//hashtbl->tbl=malloc(sizeof(struct word*)*256);

You need to uncomment that line, since without it you don't allocate the array of struct pointers in hashtbl->tbl, and leave it uninitialized. It'll probably cause a segfault as is.

Next:

for(i=0;i<256;i++)
{
  hashtbl->tbl[i] = malloc(sizeof(struct word));
  hashtbl->tbl[i] = NULL;
  //hashtbl->tbl[i]=NULL;
}

This is leaking memory. You're allocating a struct word to each element of hashtbl->tbl, but then overwriting the pointer with NULL. So you leak all the memory you allocated, and leave each array element set to NULL. Get rid of the malloc() and just set them to NULL, since you'll allocate the structs later when you actually add a word.

In this part:

hashtbl->add_fcn=&add_word;
hashtbl->remove_fcn=&remove_word;
hashtbl->hash_fcn=&hash_function;
hashtbl->toString_fcn=&toString;

...the & are not needed -- the function names without parentheses are good enough. As long as the parentheses are omitted, it will be interpreted as the address of the function and not a function call.

And then here:

    char *token = strtok(line, " ");
    while(token != NULL)
   {
      struct word *words = malloc(sizeof(struct word));
      words->s = token;

...the char * returned by strtok() typically points within the string you're processing, i.e. within the buffer you read lines into. It will not remain intact while you continue processing the file. You need to make a copy of the string, not just save the pointer.

    free(token);

...are you sure you should free this?

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! The problem was mainly the strtok and I used strcpy instead of pointing to it. Solved my problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.