Safely copying `const char *` into struct pointer

Viewed 95

I'm trying to create an instance of a struct with a const member.

Because the member is const, I'm creating a temporary value that has it initialized explicitly.

#include <string.h>
#include <stdlib.h>

typedef struct Thing {

    const char *value;

} Thing;

void createThing(const char *value) {
    
    // Create a temporary instance of Thing to initialize the const value
    Thing temporary = {
        .value = value
    };
    
    // Create a new thing
    Thing *thing = (Thing *)malloc(sizeof(Thing));
    if(thing == NULL)
        return NULL;

    // Copy the contents of temporary into the result
    memcpy(thing, &temporary, sizeof(Thing));

    // Return the result
    return thing;
}

Is it safe to use value this way, or should I create a new copy? For example:

const char *valueCopy = (char *)malloc(sizeof(char) * (strlen(value) + 1));
strcpy(valueCopy, value);

My reasoning is that the argument value will fall out of scope after the function call ends, and without copying, the value in the struct will become invalid.


As a side-note, I think I'm doing the right thing by copying from a temporary struct, but glad to be told otherwise.

1 Answers

Leaving aside the side issue of constness, the question exhibits an essential misunderstanding. Here:

Is it safe to use value this way, or should I create a new copy? For example:

const char *valueCopy = (char *)malloc(sizeof(char) * (strlen(value) + 1));
strcpy(valueCopy, value);

My reasoning is that the argument value will fall out of scope after the function call ends, and without copying, the value in the struct will become invalid.

Although it is true that function parameter value goes out of scope when execution leaves the function, that's irrelevant. The first proposed alternative initializes a structure member from the value of value. The structure member is a separate object from the function parameter. The assignment makes that object refer to the same data that value does. It does not make the member an alias for value itself. The structure member has its own lifetime, separate from and (in this case) unrelated to the lifetime of the value parameter. In that sense, then, yes, it is safe to use value as you do in the first code snippet.

HOWEVER, there are other reasons why you might want to make a copy of the pointed-to data, as well as reasons why you might want to avoid doing that. It's unclear from the question which is appropriate in your particular case. But all this is independent of the constness of the member.

Related