メモリコピーの方法 – プログラミング – Home

通知
すべてクリア

メモリコピーの方法


ごう
 ごう
(@ごう)
ゲスト
結合: 23年前
投稿: 79
Topic starter  

下記変数について、bの内容をaにコピーしたいと思っています。

DummyT a;
DummyT b = {0, 1, 2};

memcpy( (void*)&a, (void*)&b, sizeof(b) ); ・・・(1)

a = b; ・・・(2)

個人的には、aもbも同じ変数の型を持つのでサイズはまったく同じだと思います。
(1)の方法の何が問題か理解できませんでした。
(2)の方法を使うようにしたほうがいいのでようか?
(1)の方法で考えられる問題点について、ご教示ください。


引用解決済
トピックタグ
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

DummyTがPODならよいのですが,そうでないならそもそも(1)と(2)では動作が異なります。
というよりも,(1)はDummyTの作者が想定していない使い方になります。
このため,DummyTがPODである,またはこれが「純粋なCの話である」という条件が付かない
限り,(1)は「使ってはいけない」方法になります。

POD/純粋なCでも,(1)を使う必要が無い,というのもあります。
(1)のmemcpyのために<string.h>をインクルードしなくても(2)で済むのですから。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

PODの話をもう少し詳しくしてみます。

(1)の方法はDummyTがC言語の構造体であるなら、問題の無いコードです。
ちなみに、void* へのキャストは暗黙のキャストが認められていますので、
memcpy( &a, &b, sizeof(b) );
でも全く問題ありません。

同様に、PODでも問題ありません。
PODは「Plain old data structure」の略で、C言語の構造体と同等の機能しか
用いていないクラスのことです。
ではC言語の構造体以上のクラスとは何か?というと、具体例の一つが仮想関数
を含むクラスです。

仮想関数を含むクラスでは、実体(オブジェクト)を宣言すると、メンバ変数の
格納領域以外にvirtualテーブルと呼ばれる領域が確保されます。
virtualテーブルには単純にコピーするだけではまずい情報が含まれるため、
コピーすると仮想関数の仕組みが破壊されます。

また、DummyTがメンバとしてポインタ変数を持っている場合を考えましょう。
この場合、ポインタの先の領域もコピーしたいのなら、別途ポインタの先の領
域をmemcpy()した上で、コピー先の領域にポインタを更新しないといけないの
は分かるかと思います。

しかし、もし、DummyTがクラスであり、operator=()の実装を含んでいたのなら
そんな面倒なことはしなくていいのです。
(2)の方法で全てが全自動で行われるのです。

まぁ、そんなこんなで、
私自身、C++でPODのmemcpy()初期化を否定する立場ではありませんが、
PODとC++クラスの違いを完全認識した上で使うべきだと考えています。
違いが分からないで使っていると、近い将来、手痛いしっぺ返しが来ます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました