Search code examples
c

How to reassign void pointer pointing to a string to a new string in C


Let's say I have this

char *value = "old";

struct ConfigOpt {
    void *value;
};

struct ConfigOpt options[] = {
    {value}
};

options[0].value = "new";

printf("%s", value);

However, it prints out "old" instead of "new." Is there a way to set the variable to a new string by accessing it through a void pointer? I know I can pre-allocate the string, but I'd prefer to do it this way if possible.

Thanks,


Solution

  • Nothing in your code assigns value after the initializations. So obviously it will keep having the initialized value, i.e. a pointer to the string literal "old".

    If your goal really is to change value via the array options, you can do something like:

    struct ConfigOpt {
        void *value;
    };
    
    int main(void) {
        char *value = "old";
        printf("%s", value);
    
        struct ConfigOpt options[] = {
            {&value}
        };
        
        *(char**)options[0].value = "new";
    
        printf("%s", value);
        return 0;
    }
    

    This will print

    oldnew
    

    Explanation of changes:

            {&value}
             ^
             Address of
    

    The void-pointer in options[0] must be initialized to the address of value, i.e. a pointer to value. Otherwise, you can't change the actual value of value.

        *(char**)options[0].value = "new"; 
        | ^^^^^^
        | Cast back to the original type
        ^
        Dereference of the pointer to assign a new value
    

    Since options[0].value is a void pointer, you need to do a cast back to the original pointer type before you can use it for accessing the original object. The original object, i.e. value has type char*. Consequently, address of the original object has type char** which you need to use for the cast. Then when you want to access the original object, you need to dereference the char** pointer by adding a * in front - like you always do when accessing pointed-to objects.