C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 別の構造体の値が同時に変化する


(過去ログ 108 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■64381 / inTopicNo.1)  別の構造体の値が同時に変化する
  
□投稿者/ tonn (1回)-(2012/11/30(Fri) 10:50:35)

分類:[VB.NET/VB2005 以降] 

既にいない別担当の書いたvb6のソースをvb2005に移植して更に仕様変更する仕事をしているのですが、表題の現象に遭遇し悩んでいます。
ソースを抜粋し単純化するとこんな感じです。

・構造体の定義
Module Module2
    Public Const TES_MAXNUM As Short = 6 
    Structure TES_CFG
        <VBFixedArray(TES_MAXNUM)> Dim intTesType() As Short 
        Public Sub Initialize()
             ReDim intTesType(TES_MAXNUM)
        End Sub
    End Structure

    Public udtTesOldCfg As New TES_CFG 
    Public udtTesNowCfg As New TES_CFG 
End Module

・main関数(ここからスタート)
Module Module1
    Public Sub Main()
        udtTesOldCfg.Initialize()
        udtTesNowCfg.Initialize()

        Form1.ShowDialog()
    End Sub
End Module

・問題の部分
Friend Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Call ComboBox1.Items.Add("ComboBox1_1")
        Call ComboBox1.Items.Add("ComboBox1_2")
        Call ComboBox1.Items.Add("ComboBox1_3")
        Call ComboBox1.Items.Add("ComboBox1_4")
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
    'TEST用        
    If udtTesNowCfg.intTesType(1) <> udtTesOldCfg.intTesType(1) Then
            MsgBox("不一致")
        End If

        udtTesNowCfg.intTesType(1) = ComboBox1.SelectedIndex '問題の個所

    'TEST用         
    If udtTesNowCfg.intTesType(1) <> udtTesOldCfg.intTesType(1) Then
            MsgBox("不一致")
        End If
    End Sub
End Class

要はソフト起動時と変化があったかを記録して、あった場合終了時に保存するかメッセージを出すための処理です。
ここで

udtTesNowCfg.intTesType(1) = ComboBox1.SelectedIndex

の部分でudtTesNowCfg.intTesTypeだけ変えてるつもりなのですが、udtTesOldCfg.intTesTypeも同じ値に変わってしまうのです。
ちなみにこの単純化したプログラムだと現象が起きません。
実際は構造体の要素はずっと多く、この前後の処理も当然いっぱいあるのですが、特に関係しそうなところが分からないのですが。

よろしくお願い致します。

引用返信 編集キー/
■64382 / inTopicNo.2)  Re[1]: 別の構造体の値が同時に変化する
□投稿者/ Hongliang (20回)-(2012/11/30(Fri) 11:11:45)
ソースの何処かで
udtTesNowCfg.intTesType = udtTesOldCfg.intTesType
みたいなことをやってませんか?
引用返信 編集キー/
■64383 / inTopicNo.3)  Re[2]: 別の構造体の値が同時に変化する
□投稿者/ howling (108回)-(2012/11/30(Fri) 11:19:15)
No64381 (tonn さん) に返信

おはようございます。
ソースコード見ました。
ソースコード見る上では、特に問題無さそうですね…。(Initializeの中身は知りませんが)
おそらく、参照先が同じになっているから起こっていることだと思いますが、
どちらもnewしているようですしね。

普通に考えれば3つのいずれかなのかなと。

1.そもそもその構造体の中のメンバがstaticで定義されている
2.udtTesNowCfg.intTesType(1)に値をセットする時に呼ばれる(setプロパティのようなもの)の中でstaticに設定している物にアクセスしている
3.構造体udtTesNowCfgにudtTesOldCfgを代入する瞬間があり、参照したままになっている(でもnewしてますもんね)

簡潔な内容の場合に出ないあたり、そのソース自体がやっているとしか思えませんが…。
これがC++なら、内部的にメモリリークしている場合に、変な部分に対して書き込みを行ってしまうことがありますが…。(出ると厄介なやつ)
VBならきっと大丈夫なはずだよなぁと。

引用返信 編集キー/
■64384 / inTopicNo.4)  Re[3]: 別の構造体の値が同時に変化する
□投稿者/ howling (109回)-(2012/11/30(Fri) 11:24:37)
困った。迷惑投稿者扱いされてUPできない(笑

最初のメッセージボックスは表示されますか?
されるならいいんですが…。
引用返信 編集キー/
■64391 / inTopicNo.5)  Re[4]: 別の構造体の値が同時に変化する
□投稿者/ tonn (2回)-(2012/11/30(Fri) 13:42:39)
Hongliang様
howling様

回答ありがとうございます。

>udtTesNowCfg.intTesType = udtTesOldCfg.intTesType
>みたいなことをやってませんか?

その通りでした。
検索したところ何箇所かあり、試しにコメントアウトしてみると現象が出なくなりました。
vb2005の変換で元のvb6ソースがそのままになっており、6と.NETの構造体の性質の違いにより不具合が起きていたようです。

もう少し甘えさせて頂きたいのですが、、、
次のステップとして、いったんコメントアウトした部分を.NETに適合した形に直さないといけないのですがどういった処理にするのがいいでしょうか。
質問内容が変わってしまい申し訳ありませんがよろしくお願い致します。

引用返信 編集キー/
■64394 / inTopicNo.6)  Re[5]: 別の構造体の値が同時に変化する
□投稿者/ howling (112回)-(2012/11/30(Fri) 14:08:12)
2012/11/30(Fri) 15:21:33 編集(投稿者)

No64391 (tonn さん) に返信

要は、構造体の中身をコピーしたいけれども、参照渡しっぽくなってるんですかね…。
VB/C#ではクラスは値渡しではなく、参照渡しになってしまうということが原因です。
そのため、クラスの中身を1つずつ渡してあげてもいいです。
が、このクラスの中身にクラスがあった場合、
やっぱりそれの中身をまた見て1つずつ…といった再帰的な処理が必要になります。

再帰処理が膨大でめんどくさかったので、どうしようかなーと迷っていた質問を以下に。
いや、私が質問したんですがね。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=64005

↑の要点はシャローコピーではなく、ディープコピーしたいってことです。

…C#ですけど、わかりますかね?

嘘を書いてました。構造体は値型らしいです。
http://wisdom.sakura.ne.jp/programming/cs/cs31.html

初めて知ったよ…C#で構造体の使い道はあるんですねぇ。
よく調べもせずに言うんじゃなかったorz
引用返信 編集キー/
■64395 / inTopicNo.7)  Re[5]: 別の構造体の値が同時に変化する
□投稿者/ pang2 (6回)-(2012/11/30(Fri) 14:08:41)
> vb2005の変換で元のvb6ソースがそのままになっており、6と.NETの構造体の性質の違いにより不具合が起きていたようです。

VB6でもVB2005でも参照のコピーではなくディープコピーのはずだが??
もしかして、StructureではなくClassで定義してませんか?
引用返信 編集キー/
■64399 / inTopicNo.8)  Re[6]: 別の構造体の値が同時に変化する
□投稿者/ shu (109回)-(2012/11/30(Fri) 15:47:14)
No64394 (howling さん) に返信

Array.Copy(Src, Des)
でコピーする

Visual Basic 中学校より
http://homepage1.nifty.com/rucio/main/dotnet/Samples/Sample049CopyArray.htm
引用返信 編集キー/
■64403 / inTopicNo.9)  Re[6]: 別の構造体の値が同時に変化する
□投稿者/ tonn (3回)-(2012/11/30(Fri) 15:56:28)
Hongliang様

>↑の要点はシャローコピーではなく、ディープコピーしたいってことです。
>…C#ですけど、わかりますかね?

C#は経験がないのですがなんとなく要点は分かりました。
シャローコピーになってしまっているので、ディープコピーにする必要があるがその方法は要素毎にやるとかでそう簡単ではないということですね。

pang2様

>VB6でもVB2005でも参照のコピーではなくディープコピーのはずだが??
>もしかして、StructureではなくClassで定義してませんか?

Structureなんですが、問題はこのメンバが配列のせいなようです。
参考になるページがありました
http://www.papy.in/bbs/vb1/200908/09080038.html

元のVB6ソースでは起きないので、そっちは配列も値型なのかと思いますが。

原因が分かりましたし、あとは自分でごりごりやるしかないようなのでこの件は解決済みとしたいと思います。
皆様どうもありがとうございました。
解決済み
引用返信 編集キー/
■64404 / inTopicNo.10)  Re[7]: 別の構造体の値が同時に変化する
□投稿者/ howling (115回)-(2012/11/30(Fri) 16:03:23)
> Hongliang様

確かにHongliangさんは様を付けるべき存在だと僕も思います!!(笑
紛らわしくてすみませんw
でも、間違われると嬉しいやら恥ずかしいやらです。
Hongliangさんが質問してるのなんて見たことないですし。

僕はほとんどわんくま掲示板オンリーなので。
じゃんぬさん信者なのでした(ぉ
役に立ってなさそうですけどね。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -