【VC++2005 MFC】構造体のコピーについて
構造体をコピーする時、単純に「=」で代入しているのですが、先輩に
「それじゃコピー出来ないから各メンバごとに代入するような関数作れ」
と言われました。
私自身、C言語の初心者ですが、ネットで調べてみると、単純に「=」で代入出来る
ような気がしております。
ただ拝見したサイトに記載されている構造体は型が「int」「char」なのですが、
「CString」を使っていたり、構造体の中に更に構造体が入っていたりする場合も
単純に「=」で代入出来るのでしょうか?
(というか、実際にコーディング、デバッグして、コピー出来ている事は確認しているん
ですが、先輩いわく、「CStringとかのクラスが含まれている場合はダメだと思う。
メモリが壊れると思う」との事でした。)
No.1
- 回答日時:
構造体のメンバにポインタ変数がある場合に正しくコピー出来ない場合があります。
strcut Person {
char *Name;
int Age;
} Person;
Person Taro,Jiro;
memset(&Taro, 0, sizeof(Person));
memset(&Jiro, 0, sizeof(Person));
Taro.Name = malloc(20);
strcpy(Taro.Name, "太郎");
Taro.Age = 20;
としていた時に、
Jiro = Taro;
でコピーしたから、
free(Taro.Name);
としたら…
Jiro.Name はどうなるでしょう?
この回答への補足
早速のご回答ありがとうございます。
構造体の中にはポインタ変数はひとつも無いです。
上記の場合は・・・
「Jiro.Nameはfreeのタイミングで一緒に解放されてしまう」
で合ってますか?
No.2ベストアンサー
- 回答日時:
明示的にコピー代入演算子を実装しなかった場合,暗黙に定義されるコピー代入演算子は,各メンバ変数に対して
・クラスであれば再帰的にコピー代入演算子を適用
・配列であれば各要素を代入
・スカラ型であればビルトインの代入演算子を適用
となります。
ref) ISO/IEC 14882:2003 (以下IS) 12 Special member functions / 12.8 Copying class objects / paragraph 13
そのため,CStringのメンバ変数があっても,CString::operator=が呼ばれるので問題ないです。
また,コピー代入演算子の明示的な実装を持たないクラスがあった場合でも,それは「暗黙に定義されたコピー代入演算子が存在する」として扱われます。
その結果,メンバ変数は上記の法則によってコピーされます。
# クラスには,構造体や共用体を含みます (IS 9 Classes / paragraph 4)
なお,参照型のメンバ変数やconstメンバ変数があった場合,コピー代入演算子がprivateだった場合などは,暗黙に定義されるコピー代入演算子が存在しないためコンパイル時にエラーになります。
ref) IS 12 / 12.8 / paragraph 12
No.3
- 回答日時:
>「Jiro.Nameはfreeのタイミングで一緒に解放されてしまう」
>で合ってますか?
合っています。
「一緒に」というのは厳密には違いますが。ポインタは同じものを指していますので。
free()した後でTaro.Name = NULL;
しても、Jiro.NameはNULLにならずに解放済みのメモリを指したままになっています。
アクセスすれば、高確率でアウトでしょう。
# 解放直後なら触れるかも知れませんが、当然正しくない操作になります。
>構造体の中にはポインタ変数はひとつも無いです。
構造体メンバにクラスが入っていて、その中で…ということもあり得ますので、注意が必要である点には変わりない…かと。
「これから先、構造体のメンバが追加された時にポインタ変数が追加されるかも知れないから…」
ということかも知れませんし。
#2さんが書かれている通り、クラスに対してコピーコンストラクタが正しく実装されていれば大丈夫かと思われます。
ご回答ありがとうございますm(__)m
とても勉強になります。
今回の構造体には入れ子になっている構造体含めてポインタは存在しないため、
単純な代入処理のままにしておこうと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- 哲学 美大に通っている者です。美術関係の哲学を履修しています。 最近に出た課題の小テストについて、どれが正 2 2022/07/09 22:45
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- 薬学 血液脳関門の担体による通過と単純拡散による通過について教えてください 1 2022/06/29 17:32
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- 工学 西洋の教会の鐘で巨大な鐘を揺らして鳴らすのは、物理的にどんなメリットがあるの? 9 2022/12/13 08:46
- Excel(エクセル) Excelにて、セルに入力してある文字の中から文字と最後の数字のみ切り取り貼り付けるVBA 5 2022/12/27 08:40
- 不動産鑑定士・土地家屋調査士 建物の表題変更登記について お聞きします。 建物を売却するため、前所有者の作った未登記、16㎡ほどの 2 2023/02/20 17:12
- 団地・UR賃貸 単身者限定の賃貸物件について 3 2023/01/22 14:57
- Visual Basic(VBA) Excelのマクロについて教えてください。 1 2023/03/12 12:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
異なる構造体のデータのコピー
-
C++ 構造体の一括初期化 {0}
-
列挙子(enumlator)の内容を文字...
-
VB.NETのStructureというのはど...
-
long型のデータをバイト型の配...
-
構造体のデータを丸ごとコピー...
-
構造体のポインタにNULLが入らない
-
なぜ文字を扱うchar型の*qはint...
-
値が代入されてない時
-
「#undef」と「#define」の使い...
-
10進数の変換方法
-
FILE構造体がどのように定...
-
構造体の代入と比較
-
初期化リストとコンストラクタ...
-
VBAにてcolorindexを変数に格納...
-
int型とchar型について
-
変数の初期化について
-
セグメントエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
C++ 構造体の一括初期化 {0}
-
long型のデータをバイト型の配...
-
「#undef」と「#define」の使い...
-
構造体のデータを丸ごとコピー...
-
VBAにてcolorindexを変数に格納...
-
C言語 構造体の中に共用体を定...
-
値が代入されてない時
-
異なる構造体のデータのコピー
-
typedefをプログラム中で解除す...
-
構造体のポインタにNULLが入らない
-
charとucharの違い
-
整数から16進数への変換 現在c...
-
VBAの変数のデータ型を変更する...
-
VB.NETのStructureというのはど...
-
構造体を型の異なる構造体に代入
-
日付チェック関数について
-
ユーザー定義型変数の一括初期化
-
構造体の初期化方法について
おすすめ情報