'How does install() behave when NULL is stored as a name definition?

Trying to understand the code for an implementation of hash search as discussed in K&R C programming book (page 143-145).

Consider a #define statement

#define STATE 1

The aim is that we should store the name and its replacement text in a table. We create an array hashtab having pointers to linked lists. Each pointer refers to a linked list which has a name and its replacement text in each of its nodes (also with a link node, of course). If there are no names with a certain hash value, the array element at that index is NULL. For a linked list pointed to by a pointer from hashtab array, all nodes have names with common hash value.

Following are the function and struct definitions.

Here is the struct nlist. It is used to create a node which would record the name and replacement text. The node will be added in front of the already existing linked list for that hash value.

struct nlist { /* table entry: */
    struct nlist *next; /* next entry in chain */
    char *name; /* defined name */
    char *defn; /* replacement text */
};

Here is the code for the lookup() function. It searches for the string in the table and returns a pointer to the place where it was found, or NULL if the string is not present.

/* lookup: look for s in hashtab */
    struct nlist *lookup(char *s)
    {
    struct nlist *np;
    for (np = hashtab[hash(s)]; np != NULL; np = np->next)
        if (strcmp(s, np->name) == 0)
            return np; /* found */
    return NULL; /* not found */
}

The strdup() function which makes a duplicate of a string src. Error handling, for example when malloc() returns NULL, is left to the caller.

char *strdup(const char *src) {
    char *p = (char *) malloc(strlen (src) + 1);  // Space for length plus '\0'
    if (p != NULL) strcpy(p, src);
    return p;                            
}

My questions mainly concern the following install() function which records a name and replacement text in the front of the already existing linked list for that hash value.

/* install: put (name, defn) in hashtab */
struct nlist *install(char *name, char *defn)
{
    struct nlist *np;
    unsigned hashval;
    if ((np = lookup(name)) == NULL) { /* not found */
        np = (struct nlist *) malloc(sizeof(*np));
        if (np == NULL || (np->name = strdup(name)) == NULL)
            return NULL;
        hashval = hash(name);
        np->next = hashtab[hashval];
        hashtab[hashval] = np;
    } else /* already there */
        free((void *) np->defn); /*free previous defn */
    if ((np->defn = strdup(defn)) == NULL)
        return NULL;
    return np;
}

I have not written the hash() function here.

What is the significance of its return value to the main()? One more related question: The last if condition may assign NULL to np->defn (and also returns it). How will this assignment of NULL be useful to the user of install() since the first item in the list of names (having such hash values) would contain NULL in the defn? Are we allowing a name to have NULL as its definition and ignoring the reason why NULL was assigned to its defn field?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source