ジャグ配列を参照渡しして、値を変更したい

解決


まるお  2006-08-20 22:11:52  No: 132837

はじめまして。
ジャグ配列を参照渡し(ByRef)して、初期化をしたいのですが、
以下の方法で、実施することが出来ません。

下記コードの★の箇所で、以下の例外が発生してしまいます。

「System.ArgumentNullException はハンドルされませんでした。
  パラメータ名: 引数 'Array' は Nothing です。"」

「tempA(0)」と、「tempA(1)」は、正常に初期化されているのですが、
「testData.a」と、「testData.b」は、nothingのままでした。

何か変な箇所があるのでしょうか?
それとも、ジャグ配列を参照渡し(ByRef)すること自体が、NGなのでしょうか?

何かアドバイスをいただけたら、幸いです。
よろしくお願いします。

****************************以下コード****************************

Public Class Form1
    Private Structure typeTest
        Dim a() As Integer
        Dim b() As Integer
    End Structure

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim testData As typeTest
        testData.a = Nothing
        testData.b = Nothing
        Dim tempA(1)() As Integer  ' ジャグ配列を宣言

        tempA(0) = testData.a ' ジャグ配列に参照設定
        tempA(1) = testData.b ' ジャグ配列に参照設定

        '------------------------------------
        ' サブ関数でジャグ配列を初期化する
        '------------------------------------
        funcJagArrayInit(tempA) 'サブ関数にジャグ配列を参照渡し

        '------------------------------------
        '初期化できたかをチェックする
        '------------------------------------
        Debug.Print("A配列の初期化チェック")
        For i As Integer = 0 To ubound(testData.a) '★ここで例外が発生してしまう。
            Debug.Print(testData.a(i))
        Next
        Debug.Print("B配列の初期化チェック")
        For i As Integer = 0 To UBound(testData.b)
            Debug.Print(testData.b(i))
        Next

    End Sub

    Private Sub funcJagArrayInit(ByRef ref()() As Integer)
        ' ---メモリ確保 & 初期化  ---
        ReDim Preserve ref(0)(10)
        ReDim Preserve ref(1)(10)
        For i As Integer = 0 To UBound(ref(1))
            ref(0)(i) = i
            ref(1)(i) = i
        Next
    End Sub
End Class


まるお  2006-08-20 22:13:36  No: 132838

。。。開発環境を書くのを忘れてました。

VB.NET 2005
XP
です。

よろしくお願いします。


Hongliang  URL  2006-08-21 03:26:43  No: 132839

これは ByRef かどうかは問題じゃありませんね。
ReDim した時、新しいインスタンスが作成されます。で、そのインスタンスの参照は ref()() の要素に入りますが、この時点で呼び出し元 testDataとの関係は切れます。

単純にメソッドをベタ展開してみた時にどうなるか考えてみれば分かりやすいかもしれません。

tempA(0) = testData.a ' ジャグ配列に参照設定
ReDim Preserve tempA(0)(10)
For i As Integer = 0 To UBound(ref(1))
    tempA(0)(i) = i
Next

ReDim ってのは、配列を New するのと同じです(Preserve ならその後各要素をコピーします)。上記の ReDim ステートメントは、(コピーを除けば)次のように書き換えられます。
tempA(0) = New Integer(10) { }


まるお  2006-08-21 09:09:41  No: 132840

>ReDim ってのは、配列を New するのと同じです
おぉ。そうだったんですね。
恥ずかしながら、初めて知りました。

教えていただいた方法で対応したところ、OKでした!

ありがとうございました。
m(_ _)m


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加