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

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

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

Re[10]: nullreferenceexception


(過去ログ 124 を表示中)

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

■73809 / inTopicNo.1)  nullreferenceexceptionの意味と回避方法
  
□投稿者/ ちょとす (1回)-(2014/11/05(Wed) 19:55:44)

分類:[C#] 

初めまして。
現在、Note配列の中に格納されている文字列をランダムに選択し、選択された文字列をGeneType構造体のGene配列に格納していくという処理を行いたいのですが、
デバッグを行うと下のソースコードの下の方の、

Individual[i].Gene[j] = Note[RandomNumber];

の部分で、「nullreferenceexceptionはハンドルされませんでした」というメッセージが返ってきて処理が実行できません。
C#を勉強し始めて3か月ほどになるのですが、このエラーの意味と回避方法が全く分かりません。
どのようにしたらこのエラーを回避でき、Gene配列の中に文字列を格納していくことができるのでしょうか?
わかりにくいかもしれませんが、回答を頂けると非常に助かります。

以下、ソースコードです。

using System;

public struct GeneType
{
    public string[] Gene;
    public int Fitness;

    public GeneType(int geneNumber, int Fitness = 0)
    {
        this.Gene = new string[geneNumber];
        this.Fitness = Fitness;
    }
}

class Compose
{
    public static void Main()
    {
        string[] Note = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"};

        Random random = new Random();

        int geneNumber = 16;
        int indNumber = 20;

        GeneType[] Individual = new GeneType[indNumber];

        for (int i = 0; i < indNumber; i++)
        {
            for (int j = 0; j < geneNumber; j++)
            {
                int RandomNumber = random.Next(Note.Length);
                Individual[i].Gene[j] = Note[RandomNumber];
            }
        }
    }
}

引用返信 編集キー/
■73810 / inTopicNo.2)  Re[1]: nullreferenceexceptionの意味と回避方法
□投稿者/ Hongliang (247回)-(2014/11/05(Wed) 20:09:08)
> GeneType[] Individual = new GeneType[indNumber];

GeneTypeはstructであるので、この時点でIndividualの各要素にはGeneTypeインスタンスが生成されます。
されますが、このようにして生成されるstructインスタンスは、各フィールドがすべて既定値(数値型なら0とか、classなどの参照型ならnullとか)で初期化されます。
すなわち、

> Individual[i].Gene[j] = Note[RandomNumber];

のIndividual[i].Geneは(他に代入されている箇所があるわけでもないので)この時点でnullとなっています。
つまり、Geneはこの時点で実体を持っていない空っぽの存在なので、それに[j]みたいなアクセスができずNullReferenceExceptionとなります。
Geneに新しい配列を代入するなり、Indivisual[i]にnew GeneType(int, int)を代入するなりする必要があります。

VisualStudioを使って開発されているなら、デバッグ実行したときに、例外が発生した時点で例外ダイアログが表示されると思います。
そこで「中断」してやると、例外が発生した原因となるコードの箇所でブレークします。
このとき「自動変数」ウィンドウなどを確認すれば、何がnullとなっているかを確認できます。
またnew GeneType[..]の次の行にブレークポイントを設定してデバッグ実行してブレークさせれば、「ローカル」ウィンドウなどでIndivisualの構造を確認できます。
引用返信 編集キー/
■73811 / inTopicNo.3)  Re[2]: nullreferenceexceptionの意味と回避方法
□投稿者/ ちょとす (2回)-(2014/11/05(Wed) 20:52:33)
> Geneに新しい配列を代入するなり、Indivisual[i]にnew GeneType(int, int)を代入するなりする必要があります。

勉強不足過ぎてあまり理解できていませんが、←の部分にコードを書きくわえてみました。
「nullreferenceexceptionはハンドルされませんでした」というエラーは返ってきませんでしたが、Geneに1つしか文字列が格納されていないようでした。

以下、ソースコードです。

using System;

public struct GeneType
{
public string[] Gene;
public int Fitness;

public GeneType(int geneNumber, int Fitness = 0)
{
this.Gene = new string[geneNumber];
this.Fitness = Fitness;
}
}

class Compose
{
public static void Main()
{
string[] Note = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p" };

Random random = new Random();

int geneNumber = 16;
int indNumber = 20;

GeneType[] Individual = new GeneType[indNumber];


for (int i = 0; i < indNumber; i++)
{
Individual[i] = new GeneType();//<--------------------------
for (int j = 0; j < geneNumber; j++)
{
Individual[i].Gene=new string[16];//<----------------------
int RandomNumber = random.Next(Note.Length);
Individual[i].Gene[j] = Note[RandomNumber];
}
}
}
}
引用返信 編集キー/
■73812 / inTopicNo.4)  Re[3]: nullreferenceexceptionの意味と回避方法
□投稿者/ ちょとす (3回)-(2014/11/05(Wed) 20:55:47)
すみません。
図表モードになっていなかったため貼り直します。

using System;

public struct GeneType
{
    public string[] Gene;
    public int Fitness;

    public GeneType(int geneNumber, int Fitness = 0)
    {
        this.Gene = new string[geneNumber];
        this.Fitness = Fitness;
    }
}

class Compose
{
    public static void Main()
    {
        string[] Note = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p" };

        Random random = new Random();

        int geneNumber = 16;
        int indNumber = 20;

        GeneType[] Individual = new GeneType[indNumber];
        

        for (int i = 0; i < indNumber; i++)
        {
            Individual[i] = new GeneType();//<--------------------------
            for (int j = 0; j < geneNumber; j++)
            {
                Individual[i].Gene=new string[16];//<----------------------
                int RandomNumber = random.Next(Note.Length);
                Individual[i].Gene[j] = Note[RandomNumber];
            }
        }
    }
}

引用返信 編集キー/
■73813 / inTopicNo.5)  Re[3]: nullreferenceexceptionの意味と回避方法
□投稿者/ WebSurfer (373回)-(2014/11/05(Wed) 21:38:56)
No73811 (ちょとす さん) に返信

> Geneに1つしか文字列が格納されていないようでした。

どういう意味ですか?

それが、Individual[i].Gene[j] に一文字ずつしか入ってないという意味なら、そのよう
にコーディングされているので当たり前だと思いますけど。
引用返信 編集キー/
■73814 / inTopicNo.6)  Re[4]: nullreferenceexceptionの意味と回避方法
□投稿者/ ちょとす (4回)-(2014/11/05(Wed) 22:08:02)
書き方が悪かったです。

最後に

for (int i = 0; i < indNumber; i++)
        {
            for (int j = 0; j < geneNumber; j++)
            {
                Console.Write(Individual[i].Gene[j]);
            }
            Console.WriteLine("");
        }

として、中身すべてを見たのですが、

abcdefghijklmnabcdefg
abcdefghijklmnabcdefg
abcdefghijklmnabcdefg
・・・
・・・

と出力されるのではなく、

a
b
c
d
・
・
・

のように、Gene[0]からGene[15]のすべてに文字列が格納されなかったということです。

引用返信 編集キー/
■73817 / inTopicNo.7)  Re[5]: nullreferenceexception
□投稿者/ Azulean (360回)-(2014/11/05(Wed) 22:51:41)
2014/11/05(Wed) 22:55:32 編集(投稿者)

No73814 (ちょとす さん) に返信
> のように、Gene[0]からGene[15]のすべてに文字列が格納されなかったということです。

それは for (j のループで何をしているか、ちゃんと文書で説明しようとすればミスに気づけるはずです。


> Individual[i].Gene=new string[16];//<----------------------

このコードは j がカウントアップする度に毎回何をしていますか?

引用返信 編集キー/
■73818 / inTopicNo.8)  Re[6]: nullreferenceexception
□投稿者/ ちょとす (5回)-(2014/11/05(Wed) 23:05:38)
> このコードは j がカウントアップする度に毎回何をしていますか?

Geneに新しい配列を代入する必要があると考えたため、
Individual[i].Gene=new string[16];
として、Geneに箱を16個持たせようとしました。
しかし、jが増えたところでこれでは何の意味もないですね。

書き方が分からなかったので何となく書いてしまった、という感じです。
しかし、未だに全くミスに気付くことができずにいます・・・

引用返信 編集キー/
■73819 / inTopicNo.9)  Re[7]: nullreferenceexception
□投稿者/ ちょとす (6回)-(2014/11/05(Wed) 23:16:22)
修正したものです。

 for (int i = 0; i < indNumber; i++)
        {
            Individual[i] = new GeneType(geneNumber);
            for (int j = 0; j < geneNumber; j++)
            {
                int RandomNumber = random.Next(Note.Length);
                Individual[i].Gene[j] = Note[RandomNumber];
            }
        }

引用返信 編集キー/
■73820 / inTopicNo.10)  Re[8]: nullreferenceexception
□投稿者/ WebSurfer (374回)-(2014/11/05(Wed) 23:45:49)
No73819 (ちょとす さん) に返信

> Individual[i] = new GeneType(geneNumber);

ご自分で定義したコンストラクタは int 型の引数を 2 つ取りますよね? それではコンパイル
エラーになるのでは? とりあえず、

Individual[i] = new GeneType(geneNumber, i);

のようにしたらうまく行くのでは?
引用返信 編集キー/
■73821 / inTopicNo.11)  Re[9]: nullreferenceexception
□投稿者/ WebSurfer (375回)-(2014/11/05(Wed) 23:51:59)
No73820 (WebSurfer さん) に返信
> ■No73819 (ちょとす さん) に返信
>
>> Individual[i] = new GeneType(geneNumber);
>
> ご自分で定義したコンストラクタは int 型の引数を 2 つ取りますよね? それではコンパイル
> エラーになるのでは? とりあえず、
>
> Individual[i] = new GeneType(geneNumber, i);
>
> のようにしたらうまく行くのでは?

あ、すみません、GeneType(int geneNumber, int Fitness = 0) とデフォルトを定義してましたね。それなら
書かれたコードでうまく行くのではないでしょうか。

引用返信 編集キー/
■73833 / inTopicNo.12)  Re[10]: nullreferenceexception
□投稿者/ ちょとす (7回)-(2014/11/07(Fri) 21:32:26)
上のように記述したところ、エラーを回避することができました。
ありがとうございました_(._.)_
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -