3

I have this project for college where I have to create a library that processes the options of an executable from the terminal.

I created this struct options_s :

typedef struct option_s option_t;
struct option_s {
    char* keyword;
    enum { 
        OptVoid, 
        OptInt, 
        OptString, 
        OptFloat 
    } spec;
    union {
        void (*opt_void)();
        void (*opt_int)(int);
        void (*opt_str)(const char*);
        void (*opt_float)(float);
    } fct;
    option_t* next;
};

Each option type variable will hold a function that takes as a parameter an int, a float, a string or nothing. The keyword is the identifier of an option in the terminal and is for example "-o" and precedes the value that will be passed to the function.

This is how i initialize an option that takes and int as parameter :

option_t* c_null(option_t* l, const char* kw){
    l = (option_t*) malloc (sizeof(option_t));
    l->keyword = (char*) malloc (strlen(kw) + 1);
    strcpy(l->keyword, kw);
    l->next = NULL;
    return l;
}


option_t* common(option_t* l, const char* kw){
    while(l->next != NULL) l = l->next;
    l->next = (option_t*) malloc (sizeof(option_t));
    l->next->keyword = (char*) malloc (strlen(kw) + 1);
    strcpy(l->next->keyword, kw);
    l->next->next = NULL;
    return l->next;
}

option_t* opt_int(option_t* l, const char* kw, void (*f)(int)){
    if(l == NULL){
        l = c_null(l, kw);
        l->spec = OptInt;
        l->fct.opt_int = f;
        return l;
    }else{
        option_t* o = common(l, kw);
        o->spec = OptInt;
        o->fct.opt_int = f;
        return l;
    }
}

I am having problems with freeing the options. I wrote this function for that :

void opt_delete(option_t* l){
    if(l->next != NULL) opt_delete(l->next);
    free(l->keyword);
    free(l);
}

This doesn't seem to work. Even after running an option that takes in a string through this function, doing opt->fct.opt_str("foo"); will still print "foo".

What might be the problem in my code?

Zig Razor
  • 3,381
  • 2
  • 15
  • 35
  • 3
    `free()` doesn't make the memory empty or inaccessible, it just makes accessing it undefined behavior. – Fred Larson Jan 03 '20 at 14:44
  • 1
    `Names that end with ‘_t’ are reserved for additional type names.` . In other words, you should not be using the name `option_t`. – William Pursell Jan 03 '20 at 14:49
  • Ok thanks. I was unsure whether there was an actual mistake or not. – asbestos_moccasin Jan 03 '20 at 14:49
  • you don't include any code that prints out anything, so it's unclear how or why it would be printing out "foo" ? – Chris Turner Jan 03 '20 at 15:04
  • @WilliamPursell `Names that end with ‘_t’ are reserved for additional type names.` But only if they begin with `int` or `uint` I think (ref [7.31.10](http://port70.net/~nsz/c/c11/n1570.html#7.31.10)). – Ian Abbott Jan 03 '20 at 16:00
  • GNU reserves them: https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html, but I'm not really sure the scope of that document. – William Pursell Jan 03 '20 at 16:37

1 Answers1

2

The free() function doesn't clean the memory, it only deallocates the memory from the process and let the space deallocated free to be reallocated by another malloc().

This means that if you try to access to a piece of memory deallocated, you can find the last value you have written in. However this is only lucky case, because the access to an area of memory deallocated or not allocated, is an Undefined Behaviour.

This Question can help you: How do malloc() and free() work?

Zig Razor
  • 3,381
  • 2
  • 15
  • 35