1

私は機能を持っています:

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) */
   }
}

}

func(pw) を呼び出す関数は、更新された情報を取得できます。

しかし、上記のように使用しても問題ありませんか。ステートメント *pw = *save はディープ コピーではありません。pw->pw_shell = strdup(save->pw_shell) などのように、構造体のすべてのメンバーを 1 つずつコピーしたくありません。

それを行うより良い方法はありますか?

ありがとう。

4

2 に答える 2

1

必要に応じて浅いコピーを行うこともできますが、結果は次の getpenam の呼び出しまでしか有効ではありません。しかし、なぜ 2 回コピーするのでしょうか。あなたのmallocはメモリリークです! これはうまくいきます:

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.
}

ディープ コピーが必要な場合は、フィールドごとに実行する必要があります。

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
}

ディープ コピーの場合、malloc() されたストレージを解放するための対応するルーチンが必要です。

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

呼び出しを行う良い方法は次のとおりです。

// 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);
于 2012-11-14T05:08:22.703 に答える
1

関数の引数は である必要がありstruct passwd**、その後変更する必要があります*passwd

于 2012-11-14T05:00:11.273 に答える