Deutsch   English   Français   Italiano  
<v57mqf$3vq0p$5@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Lawrence D'Oliveiro <ldo@nz.invalid>
Newsgroups: comp.lang.c
Subject: Re: Fixing a sample from K&R book using cake static analyser
Date: Sat, 22 Jun 2024 23:30:23 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 57
Message-ID: <v57mqf$3vq0p$5@dont-email.me>
References: <v53sl1$35qt7$1@dont-email.me> <v558hv$3dskb$1@dont-email.me>
	<20240623022343.ec355c69a3d9eb03ad4a50f2@gmail.moc>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 23 Jun 2024 01:30:23 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="be24819e5877b282c066214411113658";
	logging-data="4188185"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+5lD/qcWfddHMte6UPkGeI"
User-Agent: Pan/0.158 (Avdiivka; )
Cancel-Lock: sha1:d6o+VKZONK45OccSu0Xx7KM0XoQ=
Bytes: 2800

On Sun, 23 Jun 2024 02:23:43 +0300, Anton Shepelev wrote:

> Why are you so afraid of `goto' ...

Look up the concept of a “Nassi-Shneiderman diagram”. It allows arbitrary 
nesting of complex code, with dynamic allocation going on, while 
minimizing flow-control headaches. The example I posted was a simple one; 
I have more complex ones if you want to see.

> I think you forget to set np->name (and to free() it in
> case of error).

Ah, didn’t notice that, since it was hidden in the middle of another line 
of code. The fix is simple. And while I’m at it, it makes sense to factor 
out the table entry disposal code into a separate routine.

    void np_free(struct nlist *np)
      {
        if (np != NULL)
          {
            free(np->name);
            free(np->defn);
          } /*if*/
        free(np);
      } /*np_free*/

    struct nlist *install(char *name, char *defn)
      {
        struct nlist *np = NULL;
        struct nlist *result = NULL;
        unsigned hashval;
        do /*once*/
          {
            result = lookup(name);
            if (result != NULL)
                break;
            np = (struct nlist *)calloc(1, sizeof struct nlist);
            if (np == NULL)
                break;
            np->name = strdup(name);
            if (np->name == NULL)
                break;
            np->defn = strdup(defn);
            if (np->defn == NULL)
                break;
            hashval = hash(name);
            np->next = hashtab[hashval];
            hashtab[hashval] = np;
            result = np;
            np = NULL; /* so I don’t dispose of it yet */
          }
        while (false);
        np_free(np);
        return
            result;
      } /*install*/