Unable to free const pointers in C

前端 未结 12 1783
梦如初夏
梦如初夏 2020-11-28 06:56

How can I free a const char*? I allocated new memory using malloc, and when I\'m trying to free it I always receive the error \"incompatible pointe

相关标签:
12条回答
  • 2020-11-28 07:28

    I think the real answer is that free should take a const pointer argument and NULL should be defined as a const pointer. This seems to be a bug in the standards. Freeing a const pointer should be implemented as follows:

    free(p);
    p = NULL;
    

    I don't see how a compiler could generate incorrect code in this case, the const pointer p is no longer accessible, so it doesn't matter if the object it pointed to is const, valid, whatever else. Its const so there can't be any dirty copies in registers or anywhere else. It is valid to set a const pointer to another value, and the fact that that value is NULL doesn't matter because the previous value is no longer accessible.

    0 讨论(0)
  • 2020-11-28 07:30

    If you are talking about pure C and you are in complete control of the memory allocation you can use the following trick to cast (const char *) to (char *) which will not give you any warning in compiler:

    const char *const_str = (const char *)malloc(...);
    char *str = NULL;
    
    union {
      char *mutable_field_p;
      const char *const_field_p;
    } u;
    
    u.const_field_p = const_str;
    str = u.mutable_field_p;
    

    Now you can use free(str); to free the memory.

    But BEWARE that this is evil beyond words and should be only used in strictly controlled environment (e.g. library which allocates and frees strings, but doesn't want to allow user to modify them) Otherwise you will end up with your program crashing when someone provides compile time "STRING" to your free function.

    0 讨论(0)
  • 2020-11-28 07:37

    There are cases you want to free a const*. However you don't want to do it unless you allocate/asign it in the same function. Else you are likely to break things. See the code below for a real world example. I use const in the function declarations to show that I am not changing the content of the arguments. However it is reassigned with a lowercased duplicate (strdup) that needs to be freed.

    char* tolowerstring(const char *to_lower)
    {
        char* workstring = strdup(to_lower);
        for(;workstring != '\0'; workstring++)
            *workstring = tolower(workstring);
        return workstring;
    }
    
    int extension_checker(const char* extension, const char* to_check)
    {
        char* tail = tolowerstring(to_check);
        extension = tolowerstring(extension);
    
        while ( (tail = strstr( tail+1, extension)) ) { /* The +1 prevents infinite loop on multiple matches */
            if ( (*extension != '.' ) && ( tail[-1] != '.'))
                continue;
            if ( tail[strlen(extension)] == '\0') {
                free(tail);
                free( (char*) extension);
                return 1;
            }
        }
        free(tail);
        free( (char *) extension);
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-28 07:40

    There's no purpose in casting a malloc'd pointer to const. Any function that takes a const pointer should not be responsible for freeing the memory that was passed to it.

    0 讨论(0)
  • 2020-11-28 07:40

    Several answers have suggested simply casting to char*. But as el.pescado wrote above,

    casting const to non-const is a symptom of code smell.

    There are compiler warnings that guard against this, such as -Wcast-qual in gcc, which I find very useful. If you really have a valid case for freeing a const pointer (contrary to what many have written here, there are valid cases, as pointed out by nlstd), you could define a macro for that purpose like this:

    #define free_const(x) free((void*)(long)(x))
    

    This works at least for gcc. The double cast makes the logic -Wcast-qual not detect this as "casting const away". Needless to say, this macro should be used with care. Actually it should only be used for pointers allocated in the same function.

    0 讨论(0)
  • 2020-11-28 07:40

    If you take a look at the signature of free function , free always takes void* ptr as an argument therefore you need to cast it to the appropriate type i.e. free((void *)str); free does not allow const pointers to be deallocated directly therefore you need to cast it to non const type

    0 讨论(0)
提交回复
热议问题