typedef struct _node{
  char *name;
  char *desc;
  struct _node *next;
}node;

#define HASHSIZE 101
static node* hashtab[HASHSIZE];


char* m_strdup(char *o){                  // the m_strdup function.......
  int l=strlen(o)+1;
  char *ns=(char*)malloc(l*sizeof(char));
  strcpy(ns,o);
  if(ns==NULL)
    return NULL;
  else
    return ns;
}


int install(char* name,char* desc){
  unsigned int hi;
  node* np;
  if((np=lookup(name))==NULL){
    hi=hash(name);
    np=(node*)malloc(sizeof(node));
    if(np==NULL)
      return 0;
    np->name=m_strdup(name);          // this assignment.......why this way?????
    if(np->name==NULL) return 0;
    np->next=hashtab[hi];
    hashtab[hi]=np;
  }
  else
    free(np->desc);
  np->desc=m_strdup(desc);                //same question........
  if(np->desc==NULL) return 0;

  return 1;
}



main(){
   char* names[]={"name","address","phone","k101","k110"};
  char* descs[]={"Sourav","Sinagor","26300788","Value1","Value2"};

  inithashtab();
   install(names[0],descs[0];                // this call....
   install(names[1],descs[1]);

  printf("Done");
}

my question is why can't we initialize np->name=name directly ? instead of copying name into another location (using m_strdup) function ..... i have tried it but np->name=name doesnot work ........any idea is appreciated......... the parts of the code to be concentrated are shown using using comments

>my question is why can't we initialize np->name=name directly ?
Well, you can if you want to, but it likely won't do what you want. Copying pointers around just means you have a bunch of aliases to the same block of memory. When people do an assignment like np->name = name; they typically want a copy of the data itself, not just a copy of the pointer.

line 13: >>char *ns=(char*)malloc(l*sizeof(char));

1) remove the typecast because C doesn't require the return value of malloc() to be typecast.

2) remove sizeof(char) because its value is guarenteed by the C languauge to always be 1.

line 14 needs to be moved down below line 16. If ns is NULL then you don't want to call strcpy().

So that function might wind up looking like this:

char* m_strdup(char *o){                  // the m_strdup function.......
  char *ns= malloc(strlen(o)+1);
  if(ns != NULL)
       strcpy(ns,o);
  return ns;
}

>2) remove sizeof(char) because its value is guarenteed by the C languauge to always be 1.
But what happens when you decide to support wide characters and forget to add it back?

>2) remove sizeof(char) because its value is guarenteed by the C languauge to always be 1.
But what happens when you decide to support wide characters and forget to add it back?

doesn't matter -- sizeof(char) is still 1.

>doesn't matter -- sizeof(char) is still 1.
Yes, but sizeof(wchar_t) may not be. Worse, you won't get any kind of warning or error if you change char to wchar_t and forget to add the size multiplier, and you'll likely be invoking undefined behavior all over the place by allocating only a fraction of the memory you think you're allocating.

This is a very dangerous bug, and because of that it's a better practice to include the multiplier, even if you know that sizeof(char) is guaranteed to be 1.

How about this: char *ns = malloc(l * sizeof(*ns));

Great! I Did not get it on the first look though

This article has been dead for over six months. Start a new discussion instead.