
C言語の構造体の勉強をしています。
構造体のデータを丸ごとコピーしたいのですが、今までは下記プログラムの★1の方法で1つ1つやっていました。
しかし変数が増えてきたのでできれば一度にコピーをしたいのですが、★2の方法では場合によってはゴミが含まれてしまいます。
そこで★3の方法で試すと今のところコピーできたのですが、これは安全なのでしょうか?
ご存知の方がおられればお願いします。
また、もっといい方法があればご伝授いただけると助かります。
#include <stdio.h>
#include <string.h>
struct Sample{
int val1;
int val2;
};
void test(Sample *p, int num){
Sample d;
switch(num){
case 1: //★1
d.val1 = p->val1;
d.val2 = p->val2;
break;
case 2: //★2
memcpy(&d, p, sizeof(Sample));
break;
case 3: //★3
d = *p;
break;
}
printf("val1:%d, val2:%d\n", d.val1, d.val2);
}
int main(){
Sample s;
s.val1 = 1;
s.val2 = 2;
test(&s, 1);
return 0;
}
No.6ベストアンサー
- 回答日時:
Cであれば、★2でも★3でも問題ありません。
★2の方法では、パディング部分の不定値もそのままコピーしますが、そもそもパディング部分にアクセスしたり、ましてやその値に依存したコードを書くこと自体間違っていますので、何の問題もありません。
ところで...
> Sample s;
という宣言を見る限り、(structが省略されているので)C++ではないかと思います。
C++の場合、memcpyで構造体をコピーできるのはC互換型(POD型)に限られます。その他のクラス(構造体を含む)をmemcpyでコピーすることはできません。
そのため、常に★3の方法を採用する方が無難です。
なお、構造体のメンバにポインタや参照を含む場合には、その参照先までコピー(すなわちディープコピー)を行うには、適切な代入演算子を定義する必要があります。
C++ではなくCの場合、専用のコピー関数を作るなどして対応する必要があります。
No.4
- 回答日時:
sizeof は「実際にメモリ上で構造体が占めるバイト数」を返します>#2.
つまり, アラインメントの都合上パディングが入る場合には, そのパディングも含めたバイト数になります. じゃないと配列を動的に確保できない.
No.2
- 回答日時:
★3でとくに問題はないです。
>★2の方法では場合によってはゴミが含まれてしまいます。
どの部分にゴミが入るかが記載されていませんが、構造体をmem系のAPIで扱うことはあまりよろしくありません。sizeof()を使用する場合も注意が必要です。
細かい理由は省きますが、「構造体で定義されているメンバの合計Byte数」=「実際にメモリ上に展開されている構造体のByte数」にはならないためです。
詳しいことは「構造体」「アライメント」「パディング」で調べてみてください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C++のcase文の書き方 4 2023/02/24 20:50
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
このQ&Aを見た人はこんなQ&Aも見ています
-
C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
C言語・C++・C#
-
C言語での引数の省略方法
C言語・C++・C#
-
「memcpy」と「strcpy」について
C言語・C++・C#
-
-
4
構造体のメンバをfor文で回したい
C言語・C++・C#
-
5
Pro c/c++ でホスト変数の後に.lenとか.arrの意味は?
C言語・C++・C#
-
6
戻り値を返す関数の前に(void)を付ける
C言語・C++・C#
-
7
typedefのスコープに関して。
C言語・C++・C#
-
8
複数の変数を宣言する時、同時に初期化?できないでしょうか?
Java
-
9
戻り値で構造体を返すことは可能でしょうか?
C言語・C++・C#
-
10
構造体配列の特定のメンバーをFor~Eachで
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
getchar,isalphaについて
-
VBAの変数のデータ型を変更する...
-
Integer変数をカラにしたいので...
-
参照なバリアント
-
「#undef」と「#define」の使い...
-
命名規則 VB 構造体
-
日付チェック関数について
-
int型とchar型について
-
typedefをプログラム中で解除す...
-
VBAにてcolorindexを変数に格納...
-
値が代入されてない時
-
CUDA言語での二次元配列のコピー
-
構造体のデータを丸ごとコピー...
-
ローカル変数の多重定義
-
変数の初期化について
-
C言語 配列の長さの上限
-
関数から配列を返すには?
-
init関数の意味
-
CStringからchar*への型変換に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
C言語 構造体の中に共用体を定...
-
構造体のデータを丸ごとコピー...
-
VBAの変数のデータ型を変更する...
-
日付チェック関数について
-
整数から16進数への変換 現在c...
-
typedefをプログラム中で解除す...
-
値が代入されてない時
-
C++ 構造体の一括初期化 {0}
-
VBAで符号無し整数
-
long型のデータをバイト型の配...
-
変数の初期化について
-
1バイトデータの読み出しについて
-
charとucharの違い
-
VBAにてcolorindexを変数に格納...
-
異なる構造体のデータのコピー
-
構造体を型の異なる構造体に代入
-
構造体にする理由・利点・使用例
おすすめ情報