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

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

新規登録して質問してみよう
ただいま回答率
85.50%
STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

9549閲覧

std::vectorの添字がうまく機能しません

ganariya

総合スコア50

STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/11/04 02:13

編集2017/11/04 03:01

###前提・実現したいこと
現在C++とSiv3Dで落ち物パズルゲームを制作しています。

###発生している問題・エラーメッセージ
std::vectorを使用して'Block'クラスを格納しようとしていたのですが
(std::vector<Block> bronzeと宣言)
bronze[0]などとアクセスしようとするとエラーが起きてしまいました。
発生した箇所はboard.cpp内のdropBronze関数です。

Expression: vector subscript out of range

###該当のソースコード

C+++

1#pragma once 2#include "Block.hpp" 3 4///<summary> 5///<para>Boardクラス</para> 6///<para>・Boardのサイズは大きい方</para> 7///<para>・位置=画面上のもの</para> 8///<para>・座標=二次元配列のこと</para> 9///</summary> 10class Board { 11 12public: 13 Board() = default; 14 Board(WhichPlayer _whichPlayer); 15 ~Board(); 16 17public: 18 const Point BOARD_VISUAL_SIZE; //見た目上の二次元配列 19 const Point BOARD_ACTUAL_SIZE; //実際の二次元配列 20 const Point BOARD_POINT_1P; //1Pの画面上の位置 21 const Point BOARD_POINT_2P; //2Pの画面上の位置 22 const Point INIT_BRONZE_COORDINATE; //ブロンズの基準の初期座標 23 const Point BOARD_RECTANGLE_SIZE; //ボードのサイズ 24 const int BLOCK_SIZE; 25 const unsigned int BRONZE_MAX_SIZE; 26 const int RED_NUM; 27 const int BLUE_NUM; 28 const int GREEN_NUM; 29 const int YELLOW_NUM; 30 const int PURPLE_NUM; 31 const int SELULIAN_NUM; 32 const int WALL_NUM; 33 const int NONE_NUM; 34 35public: 36 void init(); 37 void update(); 38 void draw() const; 39 40 void boardInit(); 41 void bronzeInit(); 42 void boardDraw() const; 43 void bronzeDraw() const; 44 45 void addBlockToBronze(Point coordinate,BlockColor blockColor); 46 void moveBronzeIndicator(int direction); 47 void dropBronze(); 48 void checkBoardConnection(); 49 50 bool isCanMoveBronze(int direction); 51 bool isCanAddBlockToBronze(); 52 bool isBronzeDontCollideWithBoard(Point _coordinate); 53 bool isReachFallingDefaultCount(); 54 55private: 56 std::vector<std::vector<BlockColor>> board; 57 std::vector<Block> bronze; 58 std::vector<Point> candidates; 59 Point bronzeIndicator; 60 WhichPlayer whichPlayer; 61 Point boardVisualPoint; 62 Rect rectangle; 63 int fallingCount; 64 int fallingDefaultCount; 65}; 66 67 68#include "Board.hpp" 69 70 71 72Board::Board(WhichPlayer _whichPlayer) : 73 whichPlayer(_whichPlayer), 74 BOARD_VISUAL_SIZE(Point(7, 13)), 75 BOARD_ACTUAL_SIZE(Point(9, 15)), 76 BOARD_POINT_1P(150, 100), 77 BOARD_POINT_2P(850, 100), 78 INIT_BRONZE_COORDINATE(3,0), 79 BOARD_RECTANGLE_SIZE(280,520), 80 BLOCK_SIZE(40), 81 BRONZE_MAX_SIZE(5), 82 RED_NUM(0), 83 BLUE_NUM(1), 84 GREEN_NUM(2), 85 YELLOW_NUM(3), 86 PURPLE_NUM(4), 87 SELULIAN_NUM(5), 88 WALL_NUM(6), 89 NONE_NUM(7) 90{ 91 init(); 92} 93 94 95Board::~Board() { 96 97} 98 99void Board::init() { 100 boardInit(); 101 bronzeInit(); 102} 103 104 105void Board::update() { 106 if (Input::Key1.clicked) { 107 dropBronze(); 108 } 109} 110 111void Board::draw() const { 112 rectangle.draw(); 113 boardDraw(); 114 bronzeDraw(); 115} 116 117void Board::boardInit() { 118 board.resize(BOARD_ACTUAL_SIZE.x); 119 for (int i = 0; i < BOARD_ACTUAL_SIZE.x; i++) { 120 board[i].resize(BOARD_ACTUAL_SIZE.y); 121 } 122 123 for (int i = 0; i < BOARD_ACTUAL_SIZE.x; i++) { 124 for (int j = 0; j < BOARD_ACTUAL_SIZE.y; j++) { 125 board[i][j] = static_cast<BlockColor>(NONE_NUM); 126 } 127 } 128 for (int i = 0; i < BOARD_ACTUAL_SIZE.x; i++) { 129 board[i][0] = static_cast<BlockColor>(WALL_NUM); 130 board[i][BOARD_ACTUAL_SIZE.y - 1] = static_cast<BlockColor>(WALL_NUM); 131 } 132 for (int i = 0; i < BOARD_ACTUAL_SIZE.y; i++) { 133 board[0][i] = static_cast<BlockColor>(WALL_NUM); 134 board[BOARD_ACTUAL_SIZE.x - 1][i] = static_cast<BlockColor>(WALL_NUM); 135 } 136 137 if (whichPlayer == WhichPlayer::PLAYER1) { 138 boardVisualPoint = BOARD_POINT_1P; 139 } 140 else { 141 boardVisualPoint = BOARD_POINT_2P; 142 } 143 rectangle = Rect(boardVisualPoint, BOARD_RECTANGLE_SIZE); 144} 145void Board::bronzeInit() { 146 bronzeIndicator = INIT_BRONZE_COORDINATE; 147 std::vector<Block>().swap(bronze); 148} 149void Board::bronzeDraw() const { 150 for (unsigned int i = 0; i<bronze.size(); i++) { 151 TextureAsset(L"Block")(BLOCK_SIZE*static_cast<int>(bronze[i].getBlockColor()), 0, BLOCK_SIZE, BLOCK_SIZE).draw(boardVisualPoint +BLOCK_SIZE*(bronzeIndicator+bronze[i].getPoint())); 152 } 153} 154void Board::boardDraw() const { 155 for (int i = 0; i < BOARD_VISUAL_SIZE.x; i++) { 156 for (int j = 0; j < BOARD_VISUAL_SIZE.y; j++) { 157 if (static_cast<int>(board[i + 1][j + 1]) < 5) { 158 TextureAsset(L"Block")(BLOCK_SIZE*static_cast<int>(board[i + 1][j + 1]), 0, BLOCK_SIZE, BLOCK_SIZE).draw(boardVisualPoint + Point(i*BLOCK_SIZE, j*BLOCK_SIZE)); 159 } 160 } 161 } 162} 163 164void Board::addBlockToBronze(Point coordinate,BlockColor blockColor) { 165 for (auto& x : bronze) { 166 x.setPoint(x.getPoint() + Point(0, 1)); 167 } 168 bronze.emplace_back(Block(blockColor,coordinate)); 169} 170 171void Board::moveBronzeIndicator(int direction) { 172 bronzeIndicator += Point(direction, 0); 173} 174 175void Board::dropBronze() { 176 Point dropBaseCoordinate = Point(0,0); 177 for (auto& x : bronze) { 178 179 } 180 // while (board[bronzeIndicator.x+1][(dropBaseCoordinate + bronze.front().getPoint()).y + 1] == BlockColor::NONE) { 181 //dropBaseCoordinate += Point(0, 1); 182 // } 183 for (auto& x : bronze) { 184 board[bronzeIndicator.x + 1][x.getPoint().y + dropBaseCoordinate.y + 1] = x.getBlockColor(); 185 } 186 187 bronze[0]; 188 bronzeInit(); 189} 190 191bool Board::isCanAddBlockToBronze() { 192 if (bronze.size() < BRONZE_MAX_SIZE) { 193 bool isCanBronzeAdd = true; 194 for (auto& x : bronze) { 195 if (!isBronzeDontCollideWithBoard(x.getPoint() + bronzeIndicator + Point(0, 1))) { 196 isCanBronzeAdd = false; 197 } 198 } 199 return isCanBronzeAdd; 200 } 201 return false; 202} 203 204bool Board::isCanMoveBronze(int direction) { 205 int valid = bronzeIndicator.x + direction; 206 if (valid >= 0 && valid < BOARD_VISUAL_SIZE.x) { 207 bool isCanBronzeMove = true; 208 for (auto& x : bronze) { 209 if (!isBronzeDontCollideWithBoard(x.getPoint()+bronzeIndicator+Point(direction,0))) { 210 isCanBronzeMove = false; 211 } 212 } 213 return isCanBronzeMove; 214 } 215 return false; 216} 217 218bool Board::isBronzeDontCollideWithBoard(Point _coordinate) { 219 if (board[_coordinate.x + 1][_coordinate.y + 1] == BlockColor::NONE) { 220 return true; 221 } 222 else { 223 return false; 224 } 225}

###試したこと
brozneをfor文やfor auto文で回した場合エラーはありませんでした。
添字アクセスまたは、front()などでアクセスしてしまうとエラーが発生しました。

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

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

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

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

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

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

yohhoy

2017/11/04 02:31 編集

オレオレ記法ではなく https://teratail.com/help/question-tips#questionTips3-7 を参考にMarkdown形式の利用をお願いします( [Block] → `Block` のように書いてください)。また、「問題を再現」する「具体的な」ソースコードを提示ください。 なお、エラーメッセージ自体は「blocksに要素が一つも含まれていない」ことを示唆しています。
ganariya

2017/11/04 03:01

質問を修正させていただきました。よろしくお願いいたします。
guest

回答1

0

ベストアンサー

yohhoyさんが既に指摘されているように、おそらく要素が空であることが原因です。

C++

1#include <iostream> 2#include <vector> 3 4void check(const std::vector<int>& vec) { 5 std::cout << "range for" << std::endl; 6 for(size_t i = 0, end_i = vec.size(); i < end_i; i++) { 7 std::cout << vec[i]; 8 } 9 std::cout << std::endl; 10 11 std::cout << "itr for" << std::endl; 12 for(auto itr = vec.cbegin(), end = vec.cend(); itr != end; itr++) { 13 std::cout << *itr; 14 } 15 std::cout << std::endl; 16 17 std::cout << "for each" << std::endl; 18 for(const auto elem: vec) { 19 std::cout << elem; 20 } 21 std::cout << std::endl; 22 23 std::cout << "front\n" 24 << vec.front() << std::endl; 25 26 std::cout << "raw index\n" 27 << vec[0] << std::endl; 28} 29 30int main(void) { 31 check({1, 2, 3}); 32 check({}); 33 return 0; 34}

実行結果

range for 123 itr for 123 for each 123 front 1 raw index 1 range for itr for for each ここで落ちる

要素数も確認せずに急に添え字アクセスするのは非常に危険です。

投稿2017/11/04 04:18

LouiS0616

総合スコア35658

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問