🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

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

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

1回答

1951閲覧

[ Dxlib ]アドレスがおかしくなる原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2021/03/22 10:02

編集2021/03/22 12:50

提示コードですがMapChip変数にmCol.変数で座標を設定してそれをIntersect関数でポインタ渡しで参照しようとすると値がおかしくなります。
なのでアドレスを表示させました。(提示コード下記) が同じアドレスが表示されてしまうのですがこれはなぜのでしょうか?よくアドレスを調べましたがわかりません。

利用ライブラリ: dxlib,glm
GitHub: https://github.com/Shigurechan/ActionGame/tree/93a1306c5a4eddb793054710ef5157717c87fb5c

イメージ説明

//ステージを読み込み void Stage::LoadStage() { printf("LoadStage\n"); mStage->clear(); //ステージをクリア // *** ステージロード *** glm::ivec2 StageSize = glm::ivec2 (0, 0); //画面サイズ FILE* fp = NULL; //ファイルポインタ // fopen_s(&fp, "Assets/Stage/Debug_AI.bin", "rb"); //読み込みモードでファイルを開く fopen_s(&fp, "Assets/Stage/Debug.bin", "rb"); //読み込みモードでファイルを開く if (fp != NULL) { //printf("あああ\n"); //ステージサイズを読み込む(先頭8バイト) fread(&StageSize.x, sizeof(int), 1, fp); fread(&StageSize.y, sizeof(int), 1, fp); for (int y = 0; y < StageSize.y; y++) { std::vector<byte> tmp; for (int x = 0; x < (int)StageSize.x; x++) { byte b = 0; fread(&b, sizeof(byte), 1, fp); tmp.push_back(b); } Stage_Grid->push_back(tmp); } fclose(fp); //ファイルを閉じる //mStage->resize(StageSize.x * StageSize.y); //マップオブジェクトを設定 for (int y = 0; y < StageSize.y; y++) { for (int x = 0; x < StageSize.x; x++) { switch (Stage_Grid->at(y).at(x)) { //ブロック case 0x01: { mStage->push_back(MapChip(Tag::Block, glm::vec2 (x * CELL, y * CELL), BlockSize, Block_sprite)); //printf("えええええ\n"); } break; //レンガ case 0x02: { mStage->push_back(MapChip(Tag::Brick, glm::vec2 (x * CELL, y * CELL), BrickSize, Brick_sprite)); } break; //ショップ case 0x03: { mStage->push_back(MapChip(Tag::Shop, glm::vec2 (x * CELL, y * CELL), ShopSize, Shop_sprite)); } break; //なし default: { // mStage->push_back(MapChip(StageObjectType::None, glm::vec2 (x * CELL, y * CELL), glm::vec2 (0, 0), -1)); }break; } } } } else { printf("ファイルを読み込めません。\n"); } // printf("%d , %d\n", mStage->at(0).getPosition().x, mStage->at(0).getPosition().y); //fclose(fp); }

cpp

1MapChip::MapChip(Tag t, glm::vec2 pos, glm::vec2 colsize,int handle) : Actor(nullptr) 2{ 3 4 5 position = pos; //座標 6 worldPosition = pos; //ワールド座標 7 sprite = handle; //スプライト 8 //printf("%f\n",size.x); 9 10 11 12 //当たり判定 13 size.x = CELL; 14 size.y = CELL; 15 16 17// mCol = std::make_shared<BoxCollision>(); 18// mCol = std::make_shared<BoxCollision>(); 19 20 minValue = position; 21 maxValue = position + size; 22 23 24 mCol.setTag(t); //タグ 25 mCol.setMin(&minValue); //最小値 26 mCol.setMax(&maxValue); //最大値 27 28 29/* 30 mCol->setTag(t); //タグ 31 mCol->setMin(&minValue); //最小値 32 mCol->setMax(&maxValue); //最大値 33 */ 34 //printf("ああああ %f %f\n", mCol->getMax().x, mCol->getMax().y); 35// printf("ああああ %f %f\n", mCol->getMin().x, mCol->getMin().y); 36 37}

cpp

1void BoxCollision::Intersect(BoxCollision *col) 2//void BoxCollision::Intersect(BoxCollision& col) 3{ 4 //printf("えええ\n"); 5 //printf("%f , %f \n",box.mMin->x,box.mMin->y); 6 //printf("%f , %f \n",box.mMax->x,box.mMax->y); 7 // 8 9 printf("%f , %f \n", col->getMin().x, col->getMin().y); 10 printf("%f , %f \n", col->getMax().x, col->getMax().y); 11 12// printf("col->getMin()"); 13 printf("\n\n"); 14 15 16 if ((col->getMax().x > box.mMin->x && box.mMax->x > col->getMin().x) 17 && (col->getMax().y > box.mMin->y && box.mMax->y > col->getMin().y)) 18 { 19 printf("true \n"); 20 setCol(true); //当たり判定を設定 21 setColTag(col->getMyTag()); //タグを取得 22 col->setColTag(getMyTag()); //タグを設定 23 24 25 if(getTriggerType() == false) 26 { 27 28 //サイズを取得 29 30 //相手 31 glm::vec2 colSize = col->getMax() - col->getMin(); 32 colSize.x = colSize.x / 2; 33 colSize.y = colSize.y / 2; 34 35 //自分 36 glm::vec2 boxSize = *box.mMax - *box.mMin; 37 boxSize.x = boxSize.x / 2; 38 boxSize.y = boxSize.y / 2; 39 40 float colCenterX = (col->getMin().x + colSize.x); 41 float colCenterY = (col->getMin().y + colSize.y); 42 float boxCenterX = (box.mMin->x + boxSize.x); 43 float boxCenterY = (box.mMin->y + boxSize.y); 44 45 46 float deltaX = boxCenterX - colCenterX; //正ならboxが右にいる 47 float deltaY = boxCenterY - colCenterY; //正ならboxが上にいる 48 float adjust = 0.0; 49 50 if (fabs(deltaX) < fabs(deltaY)) 51 { 52 // printf(", Y adjust \n"); 53 if (deltaY > 0) 54 { 55 adjust = col->getMax().y - box.mMin->y + 0.001f; // +する 56 } 57 else 58 { 59 adjust = -(box.mMax->y - col->getMin().y + 0.001f); // -する 60 } 61 box.mMin->y += adjust; 62 box.mMax->y += adjust; 63 } 64 else 65 { 66 // printf(", X adjust \n"); 67 if (deltaX > 0) 68 { 69 adjust = col->getMax().x - box.mMin->x + 0.001f; // +する 70 71 } 72 else 73 { 74 adjust = -(box.mMax->x - col->getMin().x + 0.001f); // -する 75 } 76 box.mMin->x += adjust; 77 box.mMax->x += adjust; 78 } 79 } 80 else { 81 //Trigger true 82 } 83 } 84 else 85 { 86 87 //当たってない時 88 setCol(false); 89 setColTag(Tag::Invalid); 90 col->setColTag(Tag::Invalid); 91 92 } 93 94 95 96 97} 98

cpp

1 2//最大値を取得 3glm::vec2 BoxCollision::getMax() 4{ 5 6 printf("getMax address %x\n", box.mMax); 7 8 return *box.mMax; 9} 10 11//最小値を取得 12glm::vec2 BoxCollision::getMin() 13{ 14 printf("getMin address %x\n", box.mMin); 15 16 return *box.mMin; 17} 18 19 20 21 22// #################################### 設定 関係 23 24//最大値を設定 25void BoxCollision::setMax(glm::vec2 *max) 26{ 27 box.mMax = max; 28 printf("setMax address %x\n", box.mMax); 29 30} 31 32//最小値を設定 33void BoxCollision::setMin(glm::vec2 *min) 34{ 35 box.mMin = min; 36 printf("setMin address %x\n",box.mMin); 37} 38

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

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

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

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

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

fana

2021/03/22 10:16

> printf("%f , %f \n", col->getMin().x, col->getMin().y); でチェックしている値がおかしいということならば,なにはともあれ, setMin(), setMax(), getMin(), getMax() やらいう部分のコードを示すべきでは?
退会済みユーザー

退会済みユーザー

2021/03/22 10:23

確認したのですが正しかったのでさすがに載せませんでした。
退会済みユーザー

退会済みユーザー

2021/03/22 10:27

提示コードを編集しました。
退会済みユーザー

退会済みユーザー

2021/03/22 12:50

提示コードを修正しました。
guest

回答1

0

ベストアンサー

MapChip のインスタンスは、まず Stage::LoadStage() の中で、スタック上に作られます。ループの中で作られるインスタンスはたいていはスタック上の同じアドレスに作られます。その状態で mColMapChip::minValueMapChip::maxValue のアドレスを保存しているので、だいたい同じアドレスになります。

MapChipstd::vectorに入れる時点でコピーされますし、std::vectorが伸長する度にコピーされます。コピー元は破棄されるので、コピー後の mCol に入っているアドレスは無効になります。

MapChip のコピーコンストラクタをまともに実装するか、MapChipをコピー不能にして std:vector にはスマートポインタを入れてください。私ならコピー不能にします。コピー可能にしてもメリットはないし、こういったトラブルが今後も起き続けるからです。

投稿2021/03/22 13:07

編集2021/03/22 13:14
int32_t

総合スコア21679

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

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

退会済みユーザー

退会済みユーザー

2021/03/23 01:39 編集

つまりどうすればいいのでしょうか? 追記 誤字です。
int32_t

2021/03/22 23:21 編集

回答の最後の段落に書いた通りです。回答の意味がわからなければ、何がわからないか聞いてください。「つまりどうすればいいのでしょうか?」では相手に判断を丸投げしています。
fana

2021/03/23 01:15

> mCol.setMin(&minValue); これ見て,引数の型が妙だな…とは思ったが,まさかそんな実装になっているとは予想外w. こんなん,そもそもアドレス値で持つことをやめたら良いのでは?
fana

2021/03/23 01:38 編集

MapChip型の完全な定義は不明ですが,示されたコンストラクタを見た限りだと,いくつかの数値を格納するだけの非常に簡素な構造体みたいな物と見えます. そんなものは,わざわざコピー不可にするような性質のブツではなく,単にコピーしても問題ない形の実装にすればそれで終了と思います. (コピーで問題が出るという現実装が異常なだけ) それはそれとして, > アドレスがおかしくなる原因が知りたい という話に対して,原因が回答されたわけで,それへの反応として「どうすればいいのか?」というのは違う気がするなぁ.
退会済みユーザー

退会済みユーザー

2021/03/23 01:40

質問ですが mCol.setMin(&minValue); がおかしいのでしょうか?
int32_t

2021/03/23 02:02

> mCol.setMin(&minValue); がおかしいのでしょうか? minValue のアドレスを保持することが必要であればおかしくはありません。必要であれば他のところを直さないといけません。 fanaさんが書いている通り、アドレスを保持するのをやめられるのであれば、やめたほうが良いです。
退会済みユーザー

退会済みユーザー

2021/03/23 02:14

なるほど。質問ですがアドレスでやりたい場合はコピーコンストラクタを定義する必要がるのでしょうか?
fana

2021/03/23 02:46

仮に,アドレス値で扱わねばなければならない必要性があるのだとして…… それを「最初からずっとどこぞに保持し続ける」必要があるのだろうか? 「本当にアドレス値が必要な時点でアドレスを取得して使う(その値をどこぞに長期保持しない)」形にはできないのか? (単なる矩形の2頂点の座標でしかないものに見えるのだが,何故そんなに扱いが複雑なのだろうか?)
退会済みユーザー

退会済みユーザー

2021/03/23 03:04

簡単にするべきなのですね。なるほど。 値渡しにします。仮にアドレスだった場合はコピーコンストラクタが必要なのでしょうか?
fana

2021/03/23 03:19 編集

> コピーコンストラクタが必要なのでしょうか? それ,いちいち他人に尋ねないとだめなの? "コピーコンストラクタ" をどの型に何のためにどう書くの? ふつう,俺はこれからコピーコンストラクタを書くぜ! ってときには 「コピーコンストラクタってのは… ほほう,なるほど,こういうものか…  ってことは,ここにこういう処理を書けばあれが達成できるな」 とかいう考えのもとに書くわけで. そういう考えがあるなら,コピーコンストラクタを書くか否かを他人に訊くことはあり得ないし, 考えがない状態で誰かに「コピーコンストラクタ必要だよ」と言われても意味わからなくて困るっしょ.
int32_t

2021/03/23 04:25

> コピーコンストラクタが必要なのでしょうか? 回答に書いてありますね。 コピーコンストラクタとコピー代入演算子を、コピー先がコピー元内のアドレスを保持しないよう適切に実装する必要があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問