忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

参照の落とし穴




こんにちは、シゲチィです。
ラボでは隅っこによくいます。最近、風邪こじらせてマスクしてるメガネ野郎です。

2年生はC言語からステップアップしてC++を勉強していると思います。
今回はC++の機能の一つ、参照の落とし穴について紹介したいと思います。

拍手[0回]


参照についての説明は省きます。各自で調べてください。


先日、次のような構造体を作った時の失敗について、紹介します。


sturct RGBA : public DirectX::XMFLOAT4
{    
 float& r;   // 赤
    float& g;  // 緑
    float& b;  // 青
    float& a;  // アルファ

    // コンストラクタの初期化子で参照を初期化。
    RGBA() : r(x), g(y), b(z), a(w)
    {
    } 
};



4Dベクトルのメンバを(XMFLOAT4にはx,y,z,wがメンバで含まれます。)を
r,g,b,a(カラー値)で使えるようにしようとした構造体です。


この構造体を作ったときは、RGBAで指定できるようになったぞと安易に思っていたのですが、
次の処理を行ったときにそれは起きました。



RGBA rgba;
ZeroMemory(&rgba, sizeof(rgba));
rgba.r = 1.0f;
rgba.g = 1.0f;
rgba.b = 1.0f;
rgba.a = 1.0f;



この処理を見てすぐ気付いた方はもうこの記事を閉じてもらって大丈夫です。
参照の正体を理解しているということですから。


さて、なにが起こったかというと...

3行目で実行時にエラーが発生してしまうのです。

理由はアクセス違反。r,g,b,aはXMFLOAT4のx,y,z,wを指しているのになぜなのでしょう。
実は原因は2行目の「ZeroMemory(~);」にあったのです。

RGBA構造体をバイト単位でゼロクリアしたことにより、
r,g,b,aの参照アドレス0番地になってしまっているのです(&rgba.rをすると0が取得できます)。
つまり、参照の正体はポインタのように参照先のアドレスを保持しているということ。
(このことについてはロベールのC++教室で解説されていました。)

「参照≒ポインタ」を直に感じれた失敗でした。いい経験になった・・・(しみじみ)。
みなさんは大丈夫だと思いますが、このような参照の使い方はやめましょう。
(※参照は参照先を初期時でないと指定できないため。ダウンキャストなどが危ない。)


ちなみにポインタ同様、参照をメンバにすると、
4バイトずつその分の容量も食います(構造体だとアライメント次第でどんどん肥大することも)。
これもやる内容によってはバグの原因になります(私はなりました)。

以上で今回の内容は終わりです。
長々として、ためにならなかったかな?っていう記事でしたが、
次はためになる記事になるよう努力します。
でもたまに、こういうトリビア的な内容も書いたりします。
なにか他に知りたいことがあれば、だいたいラボの隅っこにいますので、声かけてください。
PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]