回答:
構造が同じタイプであれば、はい。メモリコピーと考えてください。
はい、構造体では割り当てがサポートされています。ただし、問題があります。
struct S {
char * p;
};
struct S s1, s2;
s1.p = malloc(100);
s2 = s1;
これで、両方の構造体のポインタは同じメモリブロックを指します-コンパイラは、指し示されたデータをコピーしません。現在、どの構造体インスタンスがデータを所有しているかを知ることは困難です。これが、C ++がユーザー定義可能な代入演算子の概念を発明した理由です-このケースを処理する特定のコードを書くことができます。
struct
自身のデータは明確にコピーされます。
この例を最初に見てください:
簡単なCプログラムのCコードを以下に示します。
struct Foo {
char a;
int b;
double c;
} foo1,foo2;
void foo_assign(void)
{
foo1 = foo2;
}
int main(/*char *argv[],int argc*/)
{
foo_assign();
return 0;
}
foo_assign()の同等のASMコードは
00401050 <_foo_assign>:
401050: 55 push %ebp
401051: 89 e5 mov %esp,%ebp
401053: a1 20 20 40 00 mov 0x402020,%eax
401058: a3 30 20 40 00 mov %eax,0x402030
40105d: a1 24 20 40 00 mov 0x402024,%eax
401062: a3 34 20 40 00 mov %eax,0x402034
401067: a1 28 20 40 00 mov 0x402028,%eax
40106c: a3 38 20 40 00 mov %eax,0x402038
401071: a1 2c 20 40 00 mov 0x40202c,%eax
401076: a3 3c 20 40 00 mov %eax,0x40203c
40107b: 5d pop %ebp
40107c: c3 ret
アセンブリでは割り当てが「mov」命令に置き換えられるだけであることがわかるように、割り当て演算子は、あるメモリロケーションから別のメモリロケーションにデータを移動することを意味します。割り当ては、構造体の直接のメンバーに対してのみ実行され、構造体に複雑なデータ型がある場合はコピーに失敗します。ここでCOMPLEXは、リストを指すポインターの配列を持つことができないことを意味します。
構造体内の文字の配列自体は、ほとんどのコンパイラーでは機能しません。これは、代入がデータ型を複雑な型であると見なさずにコピーしようとするためです。
これは、あなたがそうするのと同じように、単純なコピーですmemcpy()
(実際、一部のコンパイラは実際memcpy()
にそのコードの呼び出しを生成します)。Cには「文字列」はなく、charの束へのポインタのみです。ソース構造にそのようなポインターが含まれている場合、chars自体ではなく、ポインターがコピーされます。
memcpy
、ここを参照してください:godbolt.org/z/nPxqWcを -しかし、今、私は同じポインタを渡す場合a
やb
、と*a = *b
に変換されるmemcpy
ためので、未定義の動作であることmemcpy
「メモリ領域ではない重複しなければなりません」(manページから引用)。それで、コンパイラは使用memcpy
に誤りがありますか、それともそのような割り当てを書くのに間違っていますか?
実数部と虚数部を持つ複素数のような「複雑な」という意味ですか?これはありそうにないので、「複雑な」とはC言語に関して特定のものを意味しないので、例を挙げなければならないでしょう。
構造の直接メモリコピーを取得します。それが必要かどうかは、構造によって異なります。たとえば、構造にポインタが含まれている場合、両方のコピーが同じデータを指します。これは必要な場合とそうでない場合があります。それはあなたのプログラム設計にかかっています。
「スマート」コピー(または「ディープ」コピー)を実行するには、コピーを実行する関数を実装する必要があります。これは、構造自体にポインターと、ポインターも含む構造、およびおそらくそのような構造へのポインター(おそらく「複雑な」という意味)が含まれていて、維持するのが難しい場合、達成するのが非常に困難です。単純な解決策は、C ++を使用して、構造またはクラスごとにコピーコンストラクターと代入演算子を実装することです。その後、それぞれが独自のコピーセマンティクスを担当し、代入構文を使用できます。また、より簡単に維持できます。