■この記事の概要
この記事では、C言語で構造体をコピーする際の正しい手法を解説しています。
=
演算子を用いるだけで安全かつ簡単にコピー可能であり、memcpy
の使用は誤動作を招く場合があると指摘。
異なる構造体間のコピーや個別代入のリスクについても詳しく述べています。
■構造体を代入する例
#include <stdio.h>
typedef struct {
int x;
int y;
int z;
} tag_a ;
int main(void)
{
tag_a 転送元 = {1,2,3};
tag_a 転送先 ;
転送先 = 転送元;//★OK同じ種類の構造体代入
printf("%x\n",転送先.x);
printf("%x\n",転送先.y);
printf("%x\n",転送先.z);
}
同じ種類の構造体は一発で全部代入できます。
■個別代入でメンバーを間違えた例
(warning): Redundant assignment of ‘dst->y’ to itself.
警告:自身への冗長代入[(warning)selfAssignment]
#include <stdio.h>
typedef struct {
int x;
int y;
int z;
} tag_a ;
int main(void)
{
tag_a 転送元 = {1,2,3};
tag_a 転送先 = {0};
//★NG:同じ種類の構造体代入でメンバをいちいち指定
転送先.x = 転送元.x ;
転送元.y = 転送元.y ;//★間違い
転送先.z = 転送元.z ;
printf("%x\n",転送先.x);
printf("%x\n",転送先.y);
printf("%x\n",転送先.z);
}
構造体の内容を全部代入する時は
メンバーをいちいち個別に
代入してはいけません。
メンバを間違えたり、代入が抜けたりしてしまいます。
■異種類構造体転送で間違えてmemcpyを使った例
#include <stdio.h>
#include <string.h>
typedef struct {
int x,y,z;
} tag_a ;
typedef struct {
short x,y,z;
} tag_b ;
int main(void)
{
tag_a 転送元 = {0x11111111,0x22222222,0x33333333};
tag_b 転送先 ;
//★NG:異なる種類の構造体代入でmemcpy()を使用不可
memcpy(&転送先,&転送元,sizeof(転送先));
printf("%x\n",転送先.x);
printf("%x\n",転送先.y);
printf("%x\n",転送先.z);
}
異なる種類の構造体をmemcpyで転送すると
メンバの位置が違う場合事故となります。