Menu

#44 code style: do not check pointer before free()

1.0
open
nobody
2025-04-25
2025-04-24
No

In all C standards, it is guaranteed that free() on NULL does nothing; generally it is considered bad style to check the pointer before calling free, it just complicates the code for no benefit.
https://medium.com/@Code_Analysis/shall-we-check-pointer-for-null-before-calling-free-function-63a27bb2e75e
https://stackoverflow.com/questions/6084218/is-it-good-practice-to-free-a-null-pointer-in-c

Here are some of the places where code can be simplified:
filedialog.c
change

static void free_files(FileElm *ls, int count)
{
    for(int i=0;i<count;i++) {
        if(ls[i].path) {
            free(ls[i].path);
        }
    }
    free(ls);
}

into

static void free_files(FileElm *ls, int count)
{
    for(int i=0;i<count;i++)
        free(ls[i].path);
    free(ls);
}

editorconfig.c
change

static void destroy_section(ECSection *sec) {
    if(!sec) return;
    if(sec->name) free(sec->name);

    ECKeyValue *v = sec->values;
    while(v) {
        if(v->name) free(v->name);
        if(v->value) free(v->value);
        v = v->next;
    }
}

into

static void destroy_section(ECSection *sec) {
    if(!sec) return;
    free(sec->name);

    ECKeyValue *v = sec->values;
    while(v) {
        free(v->name);
        free(v->value);
        v = v->next;
    }
}

highlight.c
change

static void freePatterns(highlightDataRec *patterns)
{
    int i;

    for (i=0; patterns[i].style!=0; i++) {
        if (patterns[i].startRE != NULL)
            free((char *)patterns[i].startRE);
        if (patterns[i].endRE != NULL)
            free((char *)patterns[i].endRE);
        if (patterns[i].errorRE != NULL)
            free((char *)patterns[i].errorRE);
        if (patterns[i].subPatternRE != NULL)
            free((char *)patterns[i].subPatternRE);
    }

    for (i=0; patterns[i].style!=0; i++) {
        NEditFree(patterns[i].subPatterns);
    }

    NEditFree(patterns);
}

into

static void freePatterns(highlightDataRec *patterns)
 {
    for (int i=0; patterns[i].style!=0; i++) {
        free(patterns[i].startRE);
        free(patterns[i].endRE);
        free(patterns[i].errorRE);
        free(patterns[i].subPatternRE);
    }

    for (int i=0; patterns[i].style!=0; i++) {
        NEditFree(patterns[i].subPatterns);
    }

    NEditFree(patterns);
}

file.c
replace 2 times

        if(ec.charset) {
            free(ec.charset);
        }

into

        free(ec.charset);

Also, since C99 is a requirement for xnedit, loop counter initialization within loop could be used in more places to simplify the code.

Discussion

  • Pyrphoros

    Pyrphoros - 2025-04-25

    Thanks for the input. I removed some of the unnecessary checks.

    The for loop (and other) declarations is another topic. There is a lot of old stuff that could be changed, however usually I only modernise functions when I want to change something.

     
  • Dusan Peterc

    Dusan Peterc - 2025-04-25

    Makes perfect sense.
    As for the unnecessary checks, I was fixing these in my own code, and some of the checks were also in the improved FSB that you wrote for me, I have checked if the same "problem" also occurred in xnedit. So I reported it, not trying to be smart.

     

Log in to post a comment.

MongoDB Logo MongoDB