none
多次元配列構造体の値の代入について RRS feed

  • 質問

  • 多次元配列構造体で、値を代入すると他の次元の変数値まで、変わってしまいます。
    構造体の定義、変数の定義などの仕方に問題があるのでしょうか?
    御存じの方がいらっしゃいましたら、ご教授頂けないでしょうか。
    宜しくおねがいします。

    【環境】
    Windows XP Pro
    Microsoft Visual Basic 2005
    .NET Framework2.0.50727

        Public Structure wGData
            Dim wKM_1 As Double
            Dim wKM_2 As Double
            Dim wKM_3 As Double
            Dim wKM_4 As Short
            Dim wKM_5 As Integer
            Dim wKM_6 As String
            Dim wKM_7 As String
            Dim wKM_8 As Integer
            Dim wKM_9 As Integer
            Dim wKM_10 As Integer
            Dim wKM_11 As Short
            Dim wKM_12 As Single
            Dim wKM_13 As Single
            Dim wKM_14 As Single
            Dim wKM_15 As Byte
            Dim wKM_16 As Integer
            Dim wKM_17 As Integer
            Dim wKM_18 As Byte
            Dim wKM_19 As Byte
            Dim wKM_20 As Byte
            Dim wKM_21 As Byte
            Dim wKM_22 As Double
            Dim wKM_23 As Double
            Dim wKM_24 As Double
            Dim wKM_25 As Double
            Dim wKM_26 As Double
            Dim wKM_27 As Double
            Dim wKM_28 As Double
            Dim wKM_29 As Double
            Dim wKM_30 As Double
            Dim wKM_31 As Double
            Dim wKM_32 As Double
            Dim wKM_33 As Double
            Dim wKM_34 As Double
            Dim wKM_35 As Double
            Dim wKM_36 As Double
            Dim wKM_37 As Double
            Dim wKM_38 As Double
            Dim wKM_39 As Double
            Dim wKM_40 As Double
            Dim wKM_41 As Double
            Dim wKM_42 As Double
            Dim wKM_43 As Double
            Dim wKM_44 As Double
            Dim wKM_45 As Double
            Dim wKM_46 As Double
            Dim wKM_47 As Double
            Dim wKM_48 As Double
            Dim wKM_49 As Double
            Dim wKM_50 As Double
            Dim wKM_51 As Double
            Dim wKM_52 As Double
            Dim wKM_53 As Double
            Dim wKM_54 As Double
            Dim wKM_55 As Double
            Dim wKM_56 As Double
            Dim wKM_57 As Double
            Dim wKM_58 As Double
            Dim wKM_59 As Double
            Dim wKM_60 As Double
            Dim wKM_61 As Double
            Dim wKM_62 As Double
            Dim wKM_63 As Double
            Dim wKM_64 As Double
            Dim wKM_65 As Double
            Dim wKM_66 As Double
            Dim wKM_67 As Double
            Dim wKM_68 As Double
        End Structure

        Public Sub Test_Sub()
            Dim wAnswer As Double
            Dim wA(,) As wGData

            ReDim wA(0, 1)

            wAnswer = wA(0, 1).wKM_2      ' wAnswer = 0

            wA(0, 0).wKM_45 = 100

            wAnswer = wA(0, 0).wKM_45    ' wAnswer = 100
            wAnswer = wA(0, 1).wKM_2      ' wAnswer = 100  代入してないのに、値が変わる

       End Sub
    2008年4月10日 1:26

回答

  •  Y開発者 さんからの引用
    新規プロジェクトで、下記のモジュールのみ追加し実行しても、
    イミディエイト ウィンドウには、

    0
    100
    と表示されます。ちなみに他の開発者のPCで、実行しても同じ結果でした。

     

    再現しました。

    ウォッチウィンドウではwKM_2は0になっていますが、

    Debug.WriteLineでは100が出ます。

     

    原因は…暇があったら調べてみたいですが、ちょっと忙しいかも。

    なので、とりいそぎ、報告を。

    2008年4月10日 5:27
  •  Y開発者 さんからの引用

    再現しましたか!! 他のところでも質問しているんですが、みなさん再現しないようで。

     

    サイズが256バイト以上の構造体でおかしくなるようです。

    一個となりに書き込んじゃいます。

     

    [code]

    Module MainModule
        <System.Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Explicit)> _
        Public Structure wGData
            <System.Runtime.InteropServices.FieldOffset(0)> _
            Dim wKM_1 As Double
            <System.Runtime.InteropServices.FieldOffset(255)> _
            Dim wKM_2 As Byte
        End Structure

        Sub Main()
            Dim wA(,) As wGData
            ReDim wA(0, 2)
            wA(0, 0).wKM_1 = 100
            System.Diagnostics.Trace.WriteLine(wA(0, 0).wKM_1) '100
            System.Diagnostics.Trace.WriteLine(wA(0, 1).wKM_1) 'なぜか100。正しくは0。
        End Sub

    End Module

    [/code]

     

    ILはきちんと吐いてるようですし、C#でも同じなので、CLRのバグですね。

    SP1を充ててないのではないでしょうか?

    SP1を充てたら正常に動くと思います。

    2008年4月10日 6:19
  • 広く情報を求めたいのであればそれを断った上で、それぞれのページにリンクするべきですよ。
    解決策が1カ所で提示されていても、アドバイスしようと調べる人の無駄な手間が増えますし、同じような悩みを抱えた人が解決策にたどり着きにくくするだけです。

     

    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=44338&forum=36&4

    http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=7289&page=0

     

     Y開発者 さんからの引用

    今、VS 2005 SP1 のダウンロード中で、1時間ぐらいかかりそうです。

    今、話に出ているのは.NET Framework 2.0 SP1のことで、VS 2005のSP1じゃ差は出ませんよ、基本的には。

     

    職場のVS2005SP1+.NET 2.0(SPなし)では再現し、VS2005SP1+.NET2.0SP1では再現しません。

    .NET2.0SP1で修正されたと考えるのが素直でしょう。

     

    参考:VistaSP1、.NET Framework 3.5、VS2008のそれぞれには.NET 2.0SP1相当が含まれる。

    2008年4月10日 13:25
    モデレータ

すべての返信

  • Y 開発者さん、こんにちは。

     

    提示して頂いたミニマム コードでこのような現象が起きることは 100% ありえません。
    そこでお聞きしたいのですが、どのように確認して wA(0, 1).wKM_2 および wAnswer の値を確認しましたか?

     

    私はデバッグ実行後に Test_Sub メソッド内でブレークして、そこからステップ実行して確認したのではと予想します。
    つまり、wA(0, 0).wKM_45 から代入した wAnswer の値と勘違いしているのではないかと考えます。


    ステップ実行中に反転している行は、「これから実行しますよ」 行であり、「今実行した行」 ではありません。
    wAnswer = wA(0, 1).wKM_2 の行が実行される以前では、wAnswer が 100.0 なのは自明です。
    実行後に wAnswer は 0.0 になるでしょう。

    2008年4月10日 2:35
  • じゃんぬねっと さん 返信ありがとうございます。

    最後の行 wAnswer = wA(0, 1).wKM_2 の下に System.Diagnostics.Debug.WriteLine(wAnswer) を付けて
    調べていますが、イミディエイト ウィンドウには、100と表示されるのです。開発環境なんでしょうか?

    2008年4月10日 2:47
  •  Y開発者 さんからの引用
    最後の行 wAnswer = wA(0, 1).wKM_2 の下に System.Diagnostics.Debug.WriteLine(wAnswer) を付けて調べていますが、イミディエイト ウィンドウには、100と表示されるのです。開発環境なんでしょうか?

     

    今、(念のため) 私の方で、ソースコードを丸々コピペして試してみましたが、やはり現象は再現できません。

    リビルドはちゃんとなされている (成功している) のですよね? 一度新規プロジェクトから試されてみては?

    2008年4月10日 2:59
  • じゃんぬねっと さん 度々ありがとうございます。

    リビルドは成功しています。何度実行しても同じ結果なんです。
    ご指摘どうり、一度新規プロジェクトから試してみます。
    結果を、後ほどご報告させて頂きます。
    2008年4月10日 3:06
  • 新規プロジェクトで、下記のモジュールのみ追加し実行しても、
    イミディエイト ウィンドウには、

    0
    100
    と表示されます。ちなみに他の開発者のPCで、実行しても同じ結果でした。
    じゃんぬねっと さんの開発環境は、

    Microsoft Visual Basic 2005
    .NET Framework2.0.50727

    ですか?

    Module MainModule
        Public Structure wGData
            Dim wKM_1 As Double
            Dim wKM_2 As Double
            Dim wKM_3 As Double
            Dim wKM_4 As Short
            Dim wKM_5 As Integer
            Dim wKM_6 As String
            Dim wKM_7 As String
            Dim wKM_8 As Integer
            Dim wKM_9 As Integer
            Dim wKM_10 As Integer
            Dim wKM_11 As Short
            Dim wKM_12 As Single
            Dim wKM_13 As Single
            Dim wKM_14 As Single
            Dim wKM_15 As Byte
            Dim wKM_16 As Integer
            Dim wKM_17 As Integer
            Dim wKM_18 As Byte
            Dim wKM_19 As Byte
            Dim wKM_20 As Byte
            Dim wKM_21 As Byte
            Dim wKM_22 As Double
            Dim wKM_23 As Double
            Dim wKM_24 As Double
            Dim wKM_25 As Double
            Dim wKM_26 As Double
            Dim wKM_27 As Double
            Dim wKM_28 As Double
            Dim wKM_29 As Double
            Dim wKM_30 As Double
            Dim wKM_31 As Double
            Dim wKM_32 As Double
            Dim wKM_33 As Double
            Dim wKM_34 As Double
            Dim wKM_35 As Double
            Dim wKM_36 As Double
            Dim wKM_37 As Double
            Dim wKM_38 As Double
            Dim wKM_39 As Double
            Dim wKM_40 As Double
            Dim wKM_41 As Double
            Dim wKM_42 As Double
            Dim wKM_43 As Double
            Dim wKM_44 As Double
            Dim wKM_45 As Double
            Dim wKM_46 As Double
            Dim wKM_47 As Double
            Dim wKM_48 As Double
            Dim wKM_49 As Double
            Dim wKM_50 As Double
            Dim wKM_51 As Double
            Dim wKM_52 As Double
            Dim wKM_53 As Double
            Dim wKM_54 As Double
            Dim wKM_55 As Double
            Dim wKM_56 As Double
            Dim wKM_57 As Double
            Dim wKM_58 As Double
            Dim wKM_59 As Double
            Dim wKM_60 As Double
            Dim wKM_61 As Double
            Dim wKM_62 As Double
            Dim wKM_63 As Double
            Dim wKM_64 As Double
            Dim wKM_65 As Double
            Dim wKM_66 As Double
            Dim wKM_67 As Double
            Dim wKM_68 As Double
        End Structure

        Sub Main()
            Call Test_Sub()
        End Sub
        Public Sub Test_Sub()
            Dim wA(,) As wGData

            ReDim wA(0, 1)

            System.Diagnostics.Debug.WriteLine(wA(0, 1).wKM_2)
            wA(0, 0).wKM_45 = 100
            System.Diagnostics.Debug.WriteLine(wA(0, 1).wKM_2) '代入してないのに、値が変わる

        End Sub

    End Module
    2008年4月10日 4:26
  •  Y開発者 さんからの引用
    新規プロジェクトで、下記のモジュールのみ追加し実行しても、
    イミディエイト ウィンドウには、

    0
    100
    と表示されます。ちなみに他の開発者のPCで、実行しても同じ結果でした。

     

    再現しました。

    ウォッチウィンドウではwKM_2は0になっていますが、

    Debug.WriteLineでは100が出ます。

     

    原因は…暇があったら調べてみたいですが、ちょっと忙しいかも。

    なので、とりいそぎ、報告を。

    2008年4月10日 5:27
  • ありえないと思って試してみましたが、結果は、期待通りの

    でした。

     

     

    VS2005 SP1のVB、VS2008のVB(.NET Framework 2.0プロジェクト)両方で同じ結果でした。

    OSはXP Pro SP2です。

    2008年4月10日 5:42
  • れい さん 返信ありがとうございます。

    再現しましたか!! 他のところでも質問しているんですが、みなさん再現しないようで。
    けど、自分だけではないので安心しました。今も色々試しているんですが、中々解決しません。
    忙しいところ、報告、本当にありがとうございました。
    2008年4月10日 5:46
  • FC-Shiro さん 返信ありがとうございます。

    やはり再現しませんか。再現する人と、再現しない人がいるみたいで・・・・・。

    【環境】Visual Studio 2005 Standard Edition / Version 8.0.50727.42
        Microsoft .NET Framework 2.0.50727

    なので、とりあえずSP1をあててみます。

    FC-Shiro さん ありがとうございました。
    2008年4月10日 6:11
  •  Y開発者 さんからの引用

    再現しましたか!! 他のところでも質問しているんですが、みなさん再現しないようで。

     

    サイズが256バイト以上の構造体でおかしくなるようです。

    一個となりに書き込んじゃいます。

     

    [code]

    Module MainModule
        <System.Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Explicit)> _
        Public Structure wGData
            <System.Runtime.InteropServices.FieldOffset(0)> _
            Dim wKM_1 As Double
            <System.Runtime.InteropServices.FieldOffset(255)> _
            Dim wKM_2 As Byte
        End Structure

        Sub Main()
            Dim wA(,) As wGData
            ReDim wA(0, 2)
            wA(0, 0).wKM_1 = 100
            System.Diagnostics.Trace.WriteLine(wA(0, 0).wKM_1) '100
            System.Diagnostics.Trace.WriteLine(wA(0, 1).wKM_1) 'なぜか100。正しくは0。
        End Sub

    End Module

    [/code]

     

    ILはきちんと吐いてるようですし、C#でも同じなので、CLRのバグですね。

    SP1を充ててないのではないでしょうか?

    SP1を充てたら正常に動くと思います。

    2008年4月10日 6:19
  • れい さん 度々返信ありがとうございます。

    お忙しいところ時間をさいて頂いて、本当にありがとうございます。
    他のところでも質問を投稿させて頂いておりまして、再現する人、再現しない人がおられる様です。
    今、VS 2005 SP1 のダウンロード中で、1時間ぐらいかかりそうです。
    結果また、報告させて頂きます。
    2008年4月10日 6:34
  • 広く情報を求めたいのであればそれを断った上で、それぞれのページにリンクするべきですよ。
    解決策が1カ所で提示されていても、アドバイスしようと調べる人の無駄な手間が増えますし、同じような悩みを抱えた人が解決策にたどり着きにくくするだけです。

     

    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=44338&forum=36&4

    http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=7289&page=0

     

     Y開発者 さんからの引用

    今、VS 2005 SP1 のダウンロード中で、1時間ぐらいかかりそうです。

    今、話に出ているのは.NET Framework 2.0 SP1のことで、VS 2005のSP1じゃ差は出ませんよ、基本的には。

     

    職場のVS2005SP1+.NET 2.0(SPなし)では再現し、VS2005SP1+.NET2.0SP1では再現しません。

    .NET2.0SP1で修正されたと考えるのが素直でしょう。

     

    参考:VistaSP1、.NET Framework 3.5、VS2008のそれぞれには.NET 2.0SP1相当が含まれる。

    2008年4月10日 13:25
    モデレータ
  • Azulean さん 返信ありがとうございます。

    Azulean さん,この投稿を見ていただいた方、申し訳ありません。
    掲示板に投稿するのが初めてでして、基本的なマナーがわかりませんでした。
    以後、気を付けたいと思います。また、投稿することが度々あるとおもいますが、
    よろしくお願いします。

    おかげさまで、.NET Framework2.0 SP1 をあてることで解決しました。
    みなさん、ありがとうございました。
    2008年4月11日 0:54
  • おお、無印限定の CLR の不具合でしたか。

    何か勘違いしているのかと決め付けるような書き方をして申し訳ありませんでした。

     

    当方の環境は SP1 でしたので再現しなかっただけのようですね。

    2008年4月11日 5:07