質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

2867閲覧

C# 配列 配列の境界外とでます

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

2クリップ

投稿2019/09/11 08:26

編集2019/09/11 08:29

範囲内なのですが例外が発生します 要素数を10に指定しているので範囲内だと思います。
ご教授お願い致します。

C#

1 2 public string[] UserNames = new string[10]; 3 4 public void UpdateMemberList()//一度だけ呼び出す 5 { 6 foreach (var p in PhotonNetwork.playerList) 7 { 8 UserMgr($"User{Count}", p.NickName);//アイコンを表示する 9 MyNumber = PhotonNetwork.playerName == p.NickName ? Count : MyNumber;//自分の背番号を取得する 10 Debug.Log($"{Count}"+ p.NickName); 11 UserNames[8] = p.NickName ?? "UserName";//配列に代入 ←8以上の数字だと例外が発生するので明示的に8と指定しました 12 ++Count; 13 } 14 } 15 16IndexOutOfRangeException: Index was outside the bounds of the array. 17(wrapper stelemref) System.Object.virt_stelemref_sealed_class(intptr,object) 18PhotonMgr.UpdateMemberList () (at Assets/Script/PhotonMgr.cs:96) 19PhotonMgr.OnJoinedRoom () (at Assets/Script/PhotonMgr.cs:83) 20UnityEngine.GameObject:SendMessage(String, Object, SendMessageOptions) 21NetworkingPeer:SendMonoMessage(PhotonNetworkingMessage, Object[]) (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:2856) 22NetworkingPeer:OnEvent(EventData) (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:2564) 23ExitGames.Client.Photon.PeerBase:DeserializeMessageAndCallback(StreamBuffer) 24ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands() 25ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands() 26PhotonHandler:Update() (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/PhotonHandler.cs:161) 27 28 29日本語訳:インデックスは配列の境界外でした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/09/11 08:28

エラー・メッセージは勝手な省略、翻訳せず、出てきたそのままコピペで提示してください
退会済みユーザー

退会済みユーザー

2019/09/11 08:31

エラーメッセージを追加しました、回答よろしくお願いいたします
Y.H.

2019/09/11 08:41

「8以上の数字だと例外が発生するので明示的に8と指定しました 」 8と指定した状態でエラーが発生するのでしょうか?
退会済みユーザー

退会済みユーザー

2019/09/11 08:46

8と指定した状態で実行するとエラーが発生します
takabosoft

2019/09/11 09:00

代入する前あたりに Debug.WriteLine(UserNames.Length); などと入れてみてUserNamesの長さが変わっていないかチェックしてみてはどうでしょう
退会済みユーザー

退会済みユーザー

2019/09/11 09:04

確認してみます
Y.H.

2019/09/11 09:07

> 8と指定した状態で実行するとエラーが発生します 8と指定した状態でキチンとビルドされてますか?
退会済みユーザー

退会済みユーザー

2019/09/11 09:18

Debug.Log($"配列要素数チェック{UserNames.Length}");で実行してみました 出力は8でした new string[10];としたのですが出力が8でした .Netフレームワーク側のバクでしょうか?
papinianus

2019/09/11 10:05

これunityですよね。詳しくないんですが、UpdateのほかStartなど呼び出しがかかりますよね。そこのコードで何かしてるほうを疑ってください。 C#の配列が10で宣言したら8になるというバグがあったら他の人が気づいてます。010は8進数の8なのでワンチャン
BluOxy

2019/09/11 10:12 編集

確かに原因がC#ではなくUnity側の可能性も考えられるので、Unityタグをつけた方が良いと思います。
退会済みユーザー

退会済みユーザー

2019/09/11 10:13

アクセスレベルをpriveteに落としたら動きました。 恐らくUnityエディター等から値を操作されていたようです 不用意にpublicで宣言してはいけないことを学びました  回答者の方々ありがとうございました。
guest

回答1

0

ベストアンサー

UserNames = new string[10];の場合、添え字でアクセスできる範囲は0から9までです。
PhotonNetwork.playerListの個数が11以上になる場合、11回目のループでUserNames[10]という存在しない要素にアクセスすることになるためIndexOutOfRangeExceptionの例外が発生します。

解決策

  • CountUserNames.Length以上のときはUserNames[Count]にアクセスしないよう修正する
  • UserNamesを配列ではなくリストで管理し、UserNames.Add(p.NickName ?? "UserName");という形で要素を追加する
  • UserNamesを配列ではなくリストで管理し、LINQを使ってUserNamesを更新する(UserNames = PhotonNetwork.playerList.Select(x => x.NickName ?? "UserName");)

投稿2019/09/11 08:46

編集2019/09/11 08:51
BluOxy

総合スコア2663

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/09/11 08:51

UserNames[8] = p.NickName ?? "UserName"; と記述しているので8にしかアクセスしないと思います。 やはりアクセスできる範囲は0から9までですよね、8は範囲なのに代入できないのは理由がわかりません 回答ありがとうございました。
BluOxy

2019/09/11 08:56

UserNamesを参照している箇所は掲示されたコードのみでしょうか。例えばUpdateMemberListが呼ばれる前に他のメソッドでUserNamesをUserNames = new string[5];のように書き換えた場合は例外が発生します。
BluOxy

2019/09/11 09:00

UpdateMemberListのどこかにDebug.Log(UserNames.Length);と書いて10がログに表示されることは確認されたでしょうか。
退会済みユーザー

退会済みユーザー

2019/09/11 09:04

確認してみます
退会済みユーザー

退会済みユーザー

2019/09/11 09:18

Debug.Log($"配列要素数チェック{UserNames.Length}");で実行してみました 出力は8でした
BluOxy

2019/09/11 09:20

VisualStudioで開いているなら、UserNamesという変数をダブルクリックし「すべての参照を検索」をクリックしてください。検索に引っかかったコードでUserNamesを書き換えてないか確認をしてください。
BluOxy

2019/09/11 09:23 編集

また、コンパイルエラーがあれば全て解消し、ビルドが完了した後に動作確認を行ってください。
退会済みユーザー

退会済みユーザー

2019/09/11 10:05 編集

すべての参照を検索から検索しても読み取りしかありませんでした、理由がわからないので配列を使わずに他の方法を使うことにしました。 回答有り難うございました
BluOxy

2019/09/11 10:09

そうですか。他に思いつく怪しい点はUserNamesがpublicなので、Unityのインスペクタ上からUserNamesを設定していないかどうかです。 何か見落としがある気はしますが、念のためスクリプト外から触られないようpublicではなくprivateで宣言した方が良いように感じます。
退会済みユーザー

退会済みユーザー

2019/09/11 10:12

アクセスレベルをpriveteに落としたら動きました。 恐らくUnityエディター等から値を操作されていたようです 不用意にpublicで宣言してはいけないことを学びました  ありがとうございました。
BluOxy

2019/09/11 10:13

そちらでしたか。解決されて良かったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問