場所 0xcdcdcdcd を読み込み中にアクセス違反

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
phelmi
記事: 18
登録日時: 13年前

場所 0xcdcdcdcd を読み込み中にアクセス違反

#1

投稿記事 by phelmi » 11年前

こんばんはc0lonと言います

今回は、std::Listを使ってソフトを作っているのですが、push_backを使うと、
「0xC0000005: 場所 0xcdcdcdcd を読み込み中にアクセス違反が発生しました。」と出ます

Windows7, Visual C++ 2010 ExpressEdition, DxLib使用です

ソースコードはこれです
SoundDefine.h

コード:

#ifndef DEF_SOUNDDEFINE_H
#define DEF_SOUNDDEFINE_H

typedef struct{
	int x, y;
}pos_t;

enum soundstate_t{
	eSStoping,
	eSPlaying,
	eSFadeIn,
	eSFadeOut,
};

struct constant_t{
	pos_t Pos;
	char name[50];
	int SndHdl;
	int TotalTime;
	int FadeInTime, FadeOutTime;
	bool bLoop;
};

struct variable_t{
	int CurrentTime;
	int Vol;
	int FadeStartVol;
	int FadeStartTime;
	bool bPause;
	soundstate_t State;
};

//実際の読み込みに使う方------------------------------------------------------------------------------------------
struct header_t{
	bool bTimeDraw;
	bool bVolDraw;
};

struct sound_t{
	const constant_t Cnst;
	variable_t Vary;
};

#endif
Sound.h

コード:

#ifndef DEF_SOUND_H
#define DEF_SOUND_H

#include <list>
#include <Singleton.h>
#include "SoundDefine.h"

class CSound : public CSingleton<CSound>{
private:
	header_t m_Header;
	std::list<sound_t> m_SoundList;

	void DataInit();

public:
	CSound();
	~CSound();

	bool Load(char FilePath[1024]);

	inline header_t GetHeader(){
		return m_Header;
	}

	inline std::list<sound_t> GetSoundList(){
		return m_SoundList;
	}
};

#endif
Sound.cpp

コード:

#include <DxLib.h>
#include "ScrReader.h"
#include "Sound.h"

CSound::CSound(){
	DataInit();
}

CSound::~CSound(){
	DataInit();
}

bool CSound::Load(char FilePath[1024]){
	CScrReader ScrReader;

	DataInit();

	SetCreateSoundDataType(DX_SOUNDDATATYPE_FILE);
	bool Result = ScrReader.GetData(&m_Header, &m_SoundList, FilePath);
	SetCreateSoundDataType(DX_SOUNDDATATYPE_MEMNOPRESS);

	return Result;
}

//private------------------------------------------------------------------------------------------

void CSound::DataInit(){
	for(std::list<sound_t>::iterator it = m_SoundList.begin(); it != m_SoundList.end();){
		DeleteSoundMem((*it).Cnst.SndHdl);
		it = m_SoundList.erase(it);
	}
	m_SoundList.clear();

	ZeroMemory(&m_Header, sizeof(m_Header));
}
ScrReader.h

コード:

#ifndef DEF_SCRREADER_H
#define DEF_SCRREADER_H

#include <list>
#include "SoundDefine.h"

class CScrReader{
private:
	bool GetHead(int FileHdl, header_t *vHeader);
	bool GetBody(int FileHdl, std::list<sound_t> *vSound);

public:
	bool GetData(header_t *vHeader, std::list<sound_t> *vList, char FilePath[1024]);
};

#endif
ScrReader.h

コード:

#include <DxLib.h>
#include <sstream>
#include "ScrReader.h"


static bool FileOpen(int *fp, char FilePath[1024]){
	*fp = FileRead_open(FilePath);

	if(*fp == 0){
		MessageBox(NULL, "指定のファイルが開けませんでした。", "エラー", MB_ICONEXCLAMATION);
		return false;
	}
	return true;
}

static bool SkipLine(int fp){
	int c;

	while(1){	//\nが出るまでループ、EOFならfalse
		c = FileRead_getc(fp);

		switch(c){
		case EOF:
			return false;
			break;
		case '\n':
			return true;
			break;
		default:
			//もう一回繰り返す
			break;
		}
	}
	return false;
}

static size_t GetNameLength(char name[]){
	const static size_t MaxByte = 24;
	size_t NameSize = strlen(name) - strlen(strrchr(name, (int)'.'));
	size_t vByte = 0;

	do{
		if(MultiByteCharCheck(&name[vByte], DX_CHARSET_SHFTJIS)){
			vByte+=2;
		}else{
			vByte++;
		}
	}while(vByte < MaxByte && vByte < NameSize);
	return vByte;
}

//ScrReader------------------------------------------------------------------------------------------
bool CScrReader::GetData(header_t *vHeader, std::list<sound_t> *vList, char FilePath[1024]){
	int FileHdl;
	if(FileOpen(&FileHdl, FilePath) == false){
		return false;
	}

	if(GetHead(FileHdl, vHeader) == false){
		goto EX_ERR;
	}

	if(GetBody(FileHdl, vList) == false){
		goto EX_ERR;
	}else{
		goto EX_OK;
	}

EX_OK:
	FileRead_close(FileHdl);
	return true;

EX_ERR:
	FileRead_close(FileHdl);
	return false;
}


//private------------------------------------------------------------------------------------------

bool CScrReader::GetHead(int FileHdl, header_t *vHeader){
	int n = FileRead_scanf(FileHdl, "%d,%d",
		&vHeader->bTimeDraw,
		&vHeader->bVolDraw
		);

	if(n != 2){
		MessageBox(NULL, "SoundData Format Error : Header", "エラー", MB_ICONEXCLAMATION);
		return false;
	}

	return SkipLine(FileHdl);	//SkipLineして、その戻り値を返す
}

bool CScrReader::GetBody(int FileHdl, std::list<sound_t> *vList){
	int line = 1;

	while(1){
		int c = FileRead_getc(FileHdl);
		switch(c){
		case EOF:
			return true;
			break;
		case '/':
			if(SkipLine(FileHdl) == false){
				return true;
			}
			break;
		default:
			FileRead_seek(FileHdl, -1, SEEK_CUR);
			break;
		}

		constant_t vCnst = {0};
		variable_t vVary = {0};

		int n = FileRead_scanf(FileHdl, "%d,%d,%d,%d,%d,%d,",		//数値データ読み込み
			&vCnst.Pos.x,
			&vCnst.Pos.y,
			&vVary.Vol,
			&vCnst.FadeInTime,
			&vCnst.FadeOutTime,
			&vCnst.bLoop
			);

		if(n != 6){		//6個でなければエラー
			std::ostringstream ostr;
			ostr << "SoundData Format Error : [" << line << "行目] [" << n << "個]";
			MessageBox(NULL, ostr.str().c_str(), "エラー", MB_ICONEXCLAMATION);
			return false;
		}

		char SoundPath[512];
		if(FileRead_gets(SoundPath, 512, FileHdl) == -1){			//行の最後までファイル名として読み込み
			std::ostringstream ostr;
			ostr << "SoundData Format Error : [" << line << "行目] [FilePath]";
			MessageBox(NULL, ostr.str().c_str(), "エラー", MB_ICONEXCLAMATION);
			return false;
		}

		vCnst.SndHdl = LoadSoundMem(SoundPath);						//音楽ファイル読み込み
		if(vCnst.SndHdl == -1){		//エラー
			std::ostringstream ostr;
			ostr << SoundPath << "が読み込めません";
			MessageBox(NULL, ostr.str().c_str(), "読み込みエラー", MB_ICONEXCLAMATION);
		}else{
			vCnst.TotalTime = GetSoundTotalTime(vCnst.SndHdl);		//総再生時間の取得
			ChangeVolumeSoundMem(vVary.Vol, vCnst.SndHdl);			//初期音量の設定

			char *str = 1 + strrchr(SoundPath, (int)'/');
			strncpy(vCnst.name, str, GetNameLength(str));			//ファイル名の決定

			sound_t vPrm = {vCnst, vVary};

			vList->push_back(vPrm);									//Listに追加
		}

		line++;		//次の行に移る
	}
	return true;
}
読み込むファイルの中身は下のようになっています

コード:

1,1
0,450,255,0,0,0,Sound/音楽ファイル1.mp3
100,300,100,0,0,1,Sound/音楽ファイル2.mp3
……
実際には、CSoundのLoadを別のところから呼び、その後GetSoundListでListを得るようになっています

何が問題なのか分からないため、困っています
よろしくお願いします

アバター
馬場自由
記事: 15
登録日時: 11年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#2

投稿記事 by 馬場自由 » 11年前

0xcdcdcdcdというのはVisualStudioが空値に割り当てる適当なアドレスで、
これが出る場合は初期化されてない変数を参照しようとしてる可能性が高いです。
push_backを呼ぶ前に初期化されてない変数が無いか調べてみてください。

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#3

投稿記事 by phelmi » 11年前

なるほど
確認してみます

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#4

投稿記事 by phelmi » 11年前

確認しましたが、初期化されていない変数は見つかりませんでした

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#5

投稿記事 by softya(ソフト屋) » 11年前

このエラーが出る場合、デバッグ開始でデバッグすれば問題箇所で止まるはずです。
ライブラリ関数の中だった場合は呼び出し履歴で遡れば問題を起こした引数が確認できるはずですので試してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#6

投稿記事 by phelmi » 11年前

>std::_Iterator_base12::operator=(const std::_Iterator_base12 & _Right) 行 124 C++
の左側に緑の矢印が表示されていますが、それ以上はよく分かりません

ヘッダの部分を読み込まないようにする(ファイルの中身も変える)と、エラーが表示されなくなります
ということは、ヘッダの部分が問題なのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#7

投稿記事 by softya(ソフト屋) » 11年前

呼び出し元の関数は何処ですか?
[補足]こちらでは動作確認出来ないので、正確な情報をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#8

投稿記事 by phelmi » 11年前

CScrReader::GetBody()中のpush_back内でエラーが発生しています

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#9

投稿記事 by softya(ソフト屋) » 11年前

GetSoundList()で受け取れるのは、m_SoundListのコピーですからインスタンスが消滅していないのか確認してもらえますか?
あとコピーにpush_back()しても意味が無い気がしますがどうやって解決しているのでしょう?

それとせっかくクラスなので、m_SoundListはCSound内にカプセル化すべきだと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#10

投稿記事 by phelmi » 11年前

ScrReaderの部分は東方龍神録のScrReaderを参考に作っています

あまりちゃんと用語を理解してはいないので、よくわからないのですが、
試作段階(ヘッダがない)では、これできちんと動いていました

[追記]
東方龍神録のC++版です

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#11

投稿記事 by softya(ソフト屋) » 11年前

c0lon さんが書きました:ScrReaderの部分は東方龍神録のScrReaderを参考に作っています

あまりちゃんと用語を理解してはいないので、よくわからないのですが、
試作段階(ヘッダがない)では、これできちんと動いていました

[追記]
東方龍神録のC++版です
東方龍神録のC++版のコードをじっくり眺めたことが無いですが、c0lonさんがちゃんと使っている保証にはなりませんのでc0lonさんがどうしているかが問題です。
管理人(Dixq)さんと全く同じように使っているのなら問題は出ないはずですが違うから問題が出てるわけですよね。

で今回の件は、GetSoundList()の戻り値を何らかのローカル変数に受け取っていると思いますが、そのローカル変数の寿命が消える関数の外まで持ちだしていませんか?って事が気になる所です。その部分のソースコードがないわけなので確認ししようがないですし。
※東方龍神録のC++版を今眺めてみましたが、GetSoundList()のようなことをしている部分は見当たりませんでした。

まぁ、一点
bool CScrReader::Get( unsigned uStage, std::vector<ScrPrm_t> *List ){
でなぜ参照ではなくポインタなんだとツッコミは管理人(Dixq)さんにしたいですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#12

投稿記事 by phelmi » 11年前

GetSoundList()を呼び出すところはまだ実装していないのですが、
ここには載せていない別のクラスのメンバ変数で受け取ろうと考えています

ScrReaderは参考にしましたが、GetSoundList()の部分は龍神録にはなく、自分で実装しました。
また、龍神録のScrReaderにはヘッダの部分はなく、これも自分で実装しました

[追記]
何度かm_SoundListのデータをコピーすることがあるので、データをCSoundで持っていて、GetSoundList()でデータをコピーしてくるのがいいかなと思ったので、こういう形になっています

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#13

投稿記事 by softya(ソフト屋) » 11年前

ちょっと流れを勘違いしてました申し訳ないです。
c0lon さんが書きました:GetSoundList()を呼び出すところはまだ実装していないのですが、
ここには載せていない別のクラスのメンバ変数で受け取ろうと考えています
中身次第ですがsound_tを返すようにすべきだと思います。出来るだけCSound内に情報は閉じ込めてください。
つまり、GetSoundList()ではなくGetSound()ぐらいに留める。あるいはもっと絞ったほうが良いです。
c0lon さんが書きました: ScrReaderは参考にしましたが、GetSoundList()の部分は龍神録にはなく、自分で実装しました。
また、龍神録のScrReaderにはヘッダの部分はなく、これも自分で実装しました
とりあえず動かしてみないと分からないので試してみます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#14

投稿記事 by softya(ソフト屋) » 11年前

残念ですが動かしてみても再現しません。
再現できる最低限の動くコードとテストデータをお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かずま

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#15

投稿記事 by かずま » 11年前

Load を呼び出す部分の載せてくれたら、解決しそうな気がします。

コード:

    // [1]
    CSound sound;
    sound.Load("some.txt");

    // [2]
    CSound *sound = new CSound;
    sound->Load("some.txt");

    // [3]
    CSound *sound;
    sound->Load("some.txt");
[1] と [2] は、クラス CSound のインスタンス(実体)が存在し、その中の
m_SoundList も、std::list<sound_t> の初期化が行われ、push_back も
問題なくできるはずです。
ところが、 [3] の場合、sound はどこを指しているかわからないし、
m_SoundList の初期化も行われません。そういう状況で、
push_back を実行すると、クラッシュする可能性が高くなります。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#16

投稿記事 by softya(ソフト屋) » 11年前

そういえば、シングルトンのはずなのにインスタンスを生成できますね。
あれ? コンストラクタとか重要なものがprivateではありません。GetInstaceもないですし。
龍神録C++と見比べてませんが、CSoundはシングルトンとして成立していません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

phelmi
記事: 18
登録日時: 13年前

Re: 場所 0xcdcdcdcd を読み込み中にアクセス違反

#17

投稿記事 by phelmi » 11年前

設計をよく考えてみれば、ここでヘッダを読み込む必要は無く、それによってエラーが発生しなくなりました。

根本的な解決ではありませんが、一旦は解決ということにさせていただきます。
softya(ソフト屋) さんが書きました:そういえば、シングルトンのはずなのにインスタンスを生成できますね。
あれ? コンストラクタとか重要なものがprivateではありません。GetInstaceもないですし。
龍神録C++と見比べてませんが、CSoundはシングルトンとして成立していません。
CSoundはシングルトンとして成立していないのですか。
ちゃんと調べようと思います

閉鎖

“C言語何でも質問掲示板” へ戻る