简体   繁体   中英

How to fill a structure when a pointer to it, is passed as an argument to a function

I have a function:

func (struct passwd* pw)
{

struct passwd* temp;
struct passwd* save;

temp = getpwnam("someuser");
/* since getpwnam returns a pointer to a static 
 * data buffer, I am copying the returned struct
 * to a local struct.
 */

if(temp) {
   save = malloc(sizeof *save);
   if (save) {
       memcpy(save, temp, sizeof(struct passwd));
       /* Here, I have to update passed pw* with this save struct. */
       *pw = *save; /* (~ memcpy) */
   }
}

}

The function which calls func(pw) is able to get the updated information.

But is it fine to use it as above. The statement *pw = *save is not a deep copy. I do not want to copy each and every member of structure one by one like pw->pw_shell = strdup(save->pw_shell) etc.

Is there any better way to do it?

Thanks.

函数参数需要是struct passwd** ,然后更改*passwd

You can do a shallow copy if you like, but the result will only be good until the next call to getpenam. But why copy twice? Your malloc is a memory leak! This will do just fine:

void func (struct passwd *pw)
{
  struct passwd *tmp = getpenam("someuser"); // get a pointer to a static struct
  *pw = *tmp;  // copy the struct to caller's storage.
}

If you want the deep copy, you have to do it field by field:

void deep_func (struct passwd *pw)
{
  struct passwd *tmp = getpenam("someuser"); // get a pointer to a static struct
  *pw = *tmp; // copy everything
  pw->pw_name = safe_strdup(pw->pw_name);  // Copy pointer contents.
  pw->pw_passwd = safe_strdup(pw->pw_passwd);
  // etc for all pointer fields
}

For the deep copy, you need a corresponding routine to free the malloc()'ed storage:

void free_passwd_fields(struct passwd *pw)
{
  free(pw->pw_name);
  free(pw->pw_passwd);
  // etc
}

A nice way to do the call is:

// Declare a 1-element array of structs.  
// No &'s are needed, so code is simplified, and a later change to malloc()/free() is very simple.
struct passwd pw[1];

// ... and later
func(pw);

// pw now behaves like a pointer to a struct, but with no malloc or free needed.
// For example:
printf("login name is %s\n", pw->pw_name);

// Done with copy.  Free it.
free_passwd_fields(pw);

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