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

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

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

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

解決済

”アクセス違反”のせいで製作が進まない・・・!

kogarashi0917
kogarashi0917

総合スコア12

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

1回答

0リアクション

0クリップ

561閲覧

投稿2021/02/22 00:20

前提・実現したいこと

Dxlibにて2Dアクションを作っています。
二次元配列に沿ってマップを描画するようなコードを書いていて、1ステージ目の走破は出来るのですが、2ステージ目に進む前にゲームが強制終了してしまいます。
エラーメッセージには
”ハンドルされない例外が 0x00007FF6E90BD6E5 (2DActionGame.exe) で発生しました: 0xC0000005: 場所 0x0000000000000105 の読み取り中にアクセス違反が発生しました。”
と書いており、ローカルや呼び出し履歴を見ても明らかにおかしいのはわかるのですが、対処の仕方がわかりません。
他の方の質問を色々調べてみたのですが、当方のプログラミングスキルはアクセス違反の意味を理解することがやっとのレベルです。
どなたか教えていただけると助かります。

発生している問題・エラーメッセージ

ハンドルされない例外が 0x00007FF6E90BD6E5 (2DActionGame.exe) で発生しました: 0xC0000005: 場所 0x0000000000000105 の読み取り中にアクセス違反が発生しました。

該当のソースコード

C++

#include "Stage.h" #include "DxLib.h" //サンプルマップデータ char g_MapDataA[STAGE_H][STAGE_W] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; //クラスに宣言した関数の実装法 //戻り値 クラス名::関数名(引数) Stage::Stage() //コンストラクタのため戻り値なし :m_PlayerStartPos() { for (int y = 0; y < STAGE_H; y++) { for (int x = 0; x < STAGE_W; x++) { switch (g_MapDataA[y][x]) { case ChipType_StartPos: m_PlayerStartPos.x = (CHIP_SIZE * x) + (HALF_CHIP); m_PlayerStartPos.y = (CHIP_SIZE * y) + (HALF_CHIP); m_Data[y][x] = ChipType_Non; break; default: m_Data[y][x] = g_MapDataA[y][x]; break; } } } } Stage::~Stage() { } void Stage::Draw() { for (int y = 0; y < STAGE_H; y++) { for (int x = 0; x < STAGE_W; x++) { //処理しない条件で判定 if (m_Data[y][x] == ChipType_Non) { continue; } /* ここを通過した時点で、何かしら描画する必要がある →DrawBoxを共通化できる */ unsigned int color = 0; //色はマップチップごとに違う //マップチップごとに分岐処理 switch (m_Data[y][x]) { case ChipType_Wall: color = GetColor(125, 125, 125); break; case ChipType_Ground: color = GetColor(0, 200, 0); break; case ChipType_Footing: color = GetColor(128, 0, 0); break; case ChipType_GoalPos: color = GetColor(255, 0, 0); break; } DrawBox( x * CHIP_SIZE, y * CHIP_SIZE, x * CHIP_SIZE + CHIP_SIZE, y * CHIP_SIZE + CHIP_SIZE, color, TRUE ); } } } //プレイヤーの初期座標の取得 //constメンバ関数…関数名にconstが後置されている関数 //関数内でメンバ変数の変更を行っていないことを保証する const Position& Stage::GetPlayerStartPos() const { return m_PlayerStartPos; } //マップとの当たり判定 //もし当たっていた場合、めり込まないように移動量 moveX_, moveY_ を補正する //当たっている辺の情報をbitフラグにして返す int Stage::CheckCollision(const Position& pos_, float* moveX_, float* moveY_) const { //当たった辺の種類 int hitFlg = 0; //現在座標に移動量を加算して、移動後の座標を出す float afterX = pos_.x; float afterY = pos_.y; afterX += (moveX_ == nullptr ? 0.0f : *moveX_); afterY += (moveY_ == nullptr ? 0.0f : *moveY_); //移動後の座標にどのようなマップチップがあるかをチェック //もし何かあれば、必要な処理を行う if (GetChipType(afterX, afterY) != ChipType_Non && GetChipType(afterX, afterY) != ChipType_GoalPos) { //2020/12/14現在、この中にはChipType_Wallの時しか来ない //すなわち、壁に接触している間の処理をここで行う //マップチップの上下左右の座標を計算 float chipLeft = int (afterX / CHIP_SIZE) * CHIP_SIZE; //左端 float chipRight = chipLeft + CHIP_SIZE; //右端 float chipTop = int (afterY / CHIP_SIZE) * CHIP_SIZE; //上端 float chipBottom = chipTop + CHIP_SIZE; //下端 //y方向のチェック if (moveY_ != nullptr) { //マップチップの上端に当たっていた場合の処理 if (*moveY_ > 0.0f) { *moveY_ = chipTop - pos_.y - 1.0f; hitFlg |= (1 << CollisionDir_Up); } //マップチップの下端に当たっていた場合の処理 else if (*moveY_ < 0.0f) { *moveY_ = chipBottom - pos_.y + 1.0f; hitFlg |= (1 << CollidionDir_Down); } } //x方向のチェック if (moveX_ != nullptr) { //マップチップの左端に当たっていた場合の処理 if (*moveX_ > 0.0f) { *moveX_ = chipLeft - pos_.x - 1.0f; hitFlg |= (1 << CollisionDir_Left); } //マップチップの右端に当たっていた場合の処理 else if (*moveX_ < 0.0f) { *moveX_ = chipRight - pos_.x + 1.0f; hitFlg |= (1 << CollisionDir_Right); } } } return hitFlg; } /* @param x_ スクリーン座標x y_ スクリーン座標y */ ChipType Stage::GetChipType(float x_, float y_) const { //画面上の座標から、配列上の座標へ変換する const int x = int(x_ / CHIP_SIZE); const int y = int(y_ / CHIP_SIZE); /* 例題:配列[1][10]はマップチップ上のどこに描画されるか? マップチップの縦横はCHIP_SIZEとする。 y = CHIP_SIZE * 1 = 32 x = CHIP_SIZE * 10 = 320 */ //配列のx、yが計算出来たら… if (x < 0 || y < 0 || x >= STAGE_W || y >= STAGE_H) { //何もなかったことにする return ChipType_Non; } //指定の座標に該当するマップの情報を返す return ChipType(m_Data[y][x]); //←ここでアクセス違反が起こる }

試したこと

補足情報(FW/ツールのバージョンなど)

使用ツール:
Visual Studio 2019
Dxlib

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。