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++ 構造体の一括初期化 {0}
C言語・C++・C#
-
構造体のメンバをfor文で回したい
C言語・C++・C#
-
-
4
異なる構造体のデータのコピー
C言語・C++・C#
-
5
C#で構造体の配列を持った構造体を使いたいのですが
C言語・C++・C#
-
6
C言語での引数の省略方法
C言語・C++・C#
-
7
構造体から他の構造体への代入
C言語・C++・C#
-
8
C++で構造体のコピーはできても == や != で比較はできないので
C言語・C++・C#
-
9
C言語のポインタに直接アドレスを割り振りしたい
C言語・C++・C#
-
10
ファイルから読み込んだデータを構造体に格納できますか?
C言語・C++・C#
-
11
構造体のコピー
Visual Basic(VBA)
-
12
構造体をコレクションに入れて扱いたいのですが…
コレクション
-
13
C言語で、メモリを解放しないで終わるプログラム
C言語・C++・C#
-
14
構造体→文字列→構造体 をする方法
Visual Basic(VBA)
-
15
deleteで開放するとエラーになる原因がわからない
C言語・C++・C#
-
16
C++:構造体:newで入れ子:deleteは?
C言語・C++・C#
-
17
【gcc・cygwin】multiple definitionエラーの解決法
C言語・C++・C#
-
18
C言語 配列の長さの上限
C言語・C++・C#
-
19
文字列から空白を取り除きたいのですが
C言語・C++・C#
-
20
16進数を10進数に簡単に変換する関数は?
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
long型のデータをバイト型の配...
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
C++ 構造体の一括初期化 {0}
-
構造体のデータを丸ごとコピー...
-
Schemeのコンストラクタの引数は?
-
HP-UXへの移植でセグメンテーシ...
-
c言語のポインタへの文字列入力...
-
C言語 配列の長さの上限
-
関数から配列を返すには?
-
init関数の意味
-
fopne で失敗する原因
-
ファイル名「1.jpg ~10.jpg~...
-
セグメントエラー
-
C言語でポインターで詰まってい...
-
市販のビンゴカードについて
-
Linked List(線形リスト)を使...
-
nullと""、\\0とEOFの違いにつ...
-
配列で格納したものをmsgboxで...
-
配列の要素数に変数を入れたい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
C++ 構造体の一括初期化 {0}
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
VBAにてcolorindexを変数に格納...
-
long型のデータをバイト型の配...
-
構造体のデータを丸ごとコピー...
-
構造体のポインタにNULLが入らない
-
VBAの変数のデータ型を変更する...
-
異なる構造体のデータのコピー
-
ユーザー定義型変数の一括初期化
-
構造体の初期化方法について
-
typedefをプログラム中で解除す...
-
C言語 構造体の中に共用体を定...
-
charとucharの違い
-
日付チェック関数について
-
整数から16進数への変換 現在c...
-
値が代入されてない時
-
命名規則 VB 構造体
-
構造体にする理由・利点・使用例
おすすめ情報