私はメンバーごとに構造体をコピーできることを知っていますが、代わりに構造体にmemcpy
を実行できますか?
そうすることをお勧めしますか?
私の構造体には、同じメンバーを持つ別の構造体にコピーする必要があるストリングもメンバーとしてあります。それ、どうやったら出来るの?
短く、読みやすく、抽象度が高いため、単純な割り当てによるコピーが最適です。 「コードの人間の読者に」「これらのビットをここからそこにコピーする」と言って、読者にコピーのサイズ引数について考えるように要求する代わりに、単純な割り当てを行います(「この値をここからここへ」)。サイズが正しいかどうかをためらうことはありません。
また、構造が非常にパディングされている場合、パディングをコピーする必要がないため(そして、それがどこにあるかを知っているため)、コンパイラーはより効率的に何かを出力する可能性がありますが、mempcy()
はそうしませんコピーするように指示した正確なバイト数が常にコピーされます。
文字列が実際の配列の場合、つまり:
struct {
char string[32];
size_t len;
} a, b;
strcpy(a.string, "hello");
a.len = strlen(a.string);
その後、プレーン割り当てを引き続き使用できます。
b = a;
完全なコピーを取得します。ただし、このようにモデル化された可変長データの場合、配列全体が常にコピーされるため、これはコピーを実行する最も効率的な方法ではありません。
ただし、ヒープに割り当てられたメモリへのポインタを含む構造体のコピーは、危険です。これを行うと、aliasingポインタになり、通常、コピー後にポインタを所有する人が曖昧になるためです。操作。
これらの状況では、「ディープコピー」が実際に唯一の選択肢であり、それを機能に組み込む必要があります。
C90以降、単純に次を使用できます。
dest_struct = source_struct;
文字列が配列内に記憶されている限り:
struct xxx {
char theString[100];
};
それ以外の場合、ポインターの場合は、手動でコピーする必要があります。
struct xxx {
char* theString;
};
dest_struct = source_struct;
dest_struct.theString = malloc(strlen(source_struct.theString) + 1);
strcpy(dest_struct.theString, source_struct.theString);
構造が互換性のあるタイプである場合、はい、次のようなものでできます:
memcpy (dest_struct, source_struct, sizeof (*dest_struct));
注意する必要があるのは、これがshallowコピーであることだけです。つまり、特定の文字列を指すchar *
がある場合、both構造体は同じ文字列を指します。
また、これらの文字列フィールドの1つのコンテンツ(char *
自体ではなく、char *
が指すデータ)を変更すると、もう一方も変更されます。
手動で各フィールドを実行する必要がなく、非浅い文字列コピーの追加ボーナスを使用して簡単なコピーが必要な場合は、strdup
を使用します。
memcpy (dest_struct, source_struct, sizeof (*dest_struct));
dest_struct->strptr = strdup (source_struct->strptr);
これにより、構造体のコンテンツ全体がコピーされ、文字列がディープコピーされ、各構造体に個別の文字列が効果的に与えられます。
また、C実装にstrdup
(ISO標準の一部ではない)がない場合は、 ここから取得 になります。
memcpy
構造体を使用することも、他の値と同様に割り当てることもできます。
struct {int a, b;} c, d;
c.a = c.b = 10;
d = c;
Cでは、memcpyは愚かに危険なだけです。 3つのパラメーターすべてを正確に取得している限り、構造体のメンバーはいずれもポインターではなく(または、浅いコピーを明示的に行うことを意図しています)、memcpyがループ処理に時間を浪費する大きな構造上のギャップはありません(またはパフォーマンスは重要ではありません)、それから必ずmemcpyです。読みづらく、将来の変更に対して脆弱で、コードレビューで手作業で検証する必要があるコード(コンパイラーができないため)以外は何も得られませんが、そうでないのは確かです。
C++では、ばかげたリスクに進みます。 std :: stringのように、安全にmemcpyableではない型のメンバーが存在する場合があります。これにより、受信する構造体が危険な武器になり、使用時にメモリがランダムに破損します。スライスコピーをエミュレートする際に、仮想関数に関する驚きを感じるかもしれません。 =をコンパイルするときに完全な型知識を保証しているため、驚くべきことを行うことができるオプティマイザーは、memcpy呼び出しに対して何も実行できません。
C++には経験則があります-memcpyまたはmemsetが表示された場合、何かが間違っています。これが当てはまらないまれなケースがありますが、構造体は含まれません。 memcpyは、blindly copy bytesの理由がある場合にのみ使用します。
一方、割り当ては読みやすく、コンパイル時に正確性をチェックし、実行時にvaluesをインテリジェントに移動します。欠点はありません。
次のソリューションを使用して、目標を達成できます。
struct student
{
char name[20];
char country[20];
};
void main()
{
struct student S={"Wolverine","America"};
struct student X;
X=S;
printf("%s%s",X.name,X.country);
}