简体   繁体   中英

C Copying to a const char *

I have a project, and I was given a header file which contains:

typedef struct User_struct {
    const char *name;
    Friends amigos;
} User;

Friends is another struct that is not in the scope of my question

In a source file I need to create, I made a struct and subsequent global variable:

typedef struct UserList{
        User *user;
        struct UserList *next;
}UserList;

static UserList *users;

There is an initialization function create_amigonet in which I allocate memory to users and another allocation to users->user . My problem is with this function:

void addUser( const char *name )
{
        UserList *new_users;
        UserList *iter;

        if(users->user->name == NULL)
        {
                users->user->name = malloc(strlen(name));
                strncpy((users->user->name,name,strlen(name));
                return;
        }

        for(iter = users; iter != NULL; iter = iter->next)
        {
                if(iter->user->name == name)
                        return;
        }

        new_users = malloc(sizeof(UserList));
        if(new_users != NULL)
        {
                new_users->user = malloc(sizeof(User));
                new_users->user->name = malloc(sizeof(name)+1);
                strncpy(new_users->user->name,name,sizeof(name)+1);
                new_users->user->amigos = NULL;
                new_users->next = users;
                users = new_users;
        }
        return;
}

I need to copy a const char * into a const char * , and I am not allowed to change the definition of the User struct or the function. I am unsure how I am supposed to copy/initialize any nodes in my structure. I can change UserList , which is a struct I created as a linked list of "users".

This is going to lead to a problem:

users->user->name = malloc(strlen(name));
strncpy((users->user->name,name,strlen(name));

It seems you don't know about null termination . Imagine you later want to read out of users->user->name . How will you know when the name ends? You didn't save the information strlen(name) anywhere.

For this reason, strings in C have a marker at the end of them. That marker is a null byte (byte of value 0 ). Then, string handling functions know where the end of the string is (and usually, the end of the allocated memory).

So you need to allocate an extra byte, and use a proper copying function:

users->user->name = malloc(strlen(name) + 1);
strcpy(users->user->name, name);

As a rule of thumb, never use strncpy . Either the strcpy or the snprintf function is more appropriate. strncpy is a relic from days of yore.

You have a similar (but even worse, since you lapsed into using sizeof without actually understanding what sizeof does) later in your program. Hopefully you can now fix that too, after reading my answer.

I need to copy a const char * into a const char *,

You need to stop thinking of a pointer as "containing" anything. Pointers point to other parts of memory which must, in of themselves, exist.

You need to copy some bytes from one place to another, where you have pointers to both locations.

Now, you can't write to a location via a const char * . That's what const is for. However, the location is not in read-only memory: you just malloc'd it. So the location is definitely safe to write. You just need to rearrange your code so you pass a non-const pointer to the writing function. One way of doing that would be:

char *new_name = malloc(strlen(name) + 1);
strcpy(new_name, name);
users->user->name = new_name;

Another way, if you are on a POSIX system, would be:

users->user->name = strdup(name);

which has the same effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM