提示コードのPlayerクラスのUpdate()関数部ですがif()文の攻撃コメント部ですが。ここでpush_backしてその下のfor文で全部削除してデストラクタのprintf()が表示されてしっかりと廃棄されているはずなのですがなぜメモリリークしてしまうのでしょうか?またコピーコンストラクタもしっかり定義されておりデストラクタもしっかりdelete mSprite;と書いて居るのですがなぜでしょうか?
場所はBullet クラスのnew している部分で片方をコメントアウトしてもリークするので両方が原因と思うのですがどうすればいいのでしょうか?
cpp
1#include "../../Header/Game/Player.hpp" 2 3// コンストラクタ 4Player::Player(class Game* g,const char* fileName ) : Actor_2D() 5{ 6 Owner = g; //Game クラス 7 8 mSprite = new Sprite(Owner,fileName); // スプライトクラス 9 mInput = new Input_Key(Owner); // キー入力クラス 10 mSpeed = SPEED; // 移動速度 11 mVector = glm::vec2(0,1); // 方向 12 13 mKeyCode = Key_Code::Up; 14 15 16 // RIGHT 17 mSpriteNum.at(0).at(0).at(0).x = 0; 18 mSpriteNum.at(0).at(0).at(0).y = 0; 19 mSpriteNum.at(0).at(0).at(1).x = CELL - 1; 20 mSpriteNum.at(0).at(0).at(1).y = CELL - 1; 21 22 mSpriteNum.at(0).at(1).at(0).x = 0; 23 mSpriteNum.at(0).at(1).at(0).y = CELL - 1; 24 mSpriteNum.at(0).at(1).at(1).x = CELL - 1; 25 mSpriteNum.at(0).at(1).at(1).y = CELL * 2 - 1; 26 27 // DOWN 28 mSpriteNum.at(1).at(0).at(0).x = CELL; 29 mSpriteNum.at(1).at(0).at(0).y = 1; 30 mSpriteNum.at(1).at(0).at(1).x = CELL * 2 - 1; 31 mSpriteNum.at(1).at(0).at(1).y = CELL - 1; 32 33 mSpriteNum.at(1).at(1).at(0).x = CELL - 0; 34 mSpriteNum.at(1).at(1).at(0).y = CELL + 1; 35 mSpriteNum.at(1).at(1).at(1).x = CELL * 2 - 1; 36 mSpriteNum.at(1).at(1).at(1).y = CELL * 2 - 1; 37 38 // UP 39 mSpriteNum.at(2).at(0).at(0).x = CELL * 2 + 1; 40 mSpriteNum.at(2).at(0).at(0).y = 1; 41 mSpriteNum.at(2).at(0).at(1).x = CELL * 3; 42 mSpriteNum.at(2).at(0).at(1).y = CELL - 1; 43 44 mSpriteNum.at(2).at(1).at(0).x = CELL * 2 + 1; 45 mSpriteNum.at(2).at(1).at(0).y = CELL + 1; 46 mSpriteNum.at(2).at(1).at(1).x = CELL * 3 - 1; 47 mSpriteNum.at(2).at(1).at(1).y = CELL * 2 - 1; 48 49 // LEFT 50 mSpriteNum.at(3).at(0).at(0).x = CELL * 3 + 1; 51 mSpriteNum.at(3).at(0).at(0).y = 1; 52 mSpriteNum.at(3).at(0).at(1).x = CELL * 4; 53 mSpriteNum.at(3).at(0).at(1).y = CELL - 1; 54 55 mSpriteNum.at(3).at(1).at(0).x = CELL * 3 + 1; 56 mSpriteNum.at(3).at(1).at(0).y = CELL + 1; 57 mSpriteNum.at(3).at(1).at(1).x = CELL * 4 - 1; 58 mSpriteNum.at(3).at(1).at(1).y = CELL * 2 - 1; 59 60} 61 62// 計算 63void Player::Update() 64{ 65 // キー入力 66 mSpeed = SPEED; 67 if (mInput->KeyDownHold(GLFW_KEY_LEFT) == true) 68 { 69 mVector.x = -1.0f; 70 mVector.y = 0.0f; 71 mKeyCode = Key_Code::Left; 72 } 73 else if (mInput->KeyDownHold(GLFW_KEY_RIGHT) == true) 74 { 75 mVector.x = 1.0f; 76 mVector.y = 0.0f; 77 mKeyCode = Key_Code::Right; 78 79 } 80 else if (mInput->KeyDownHold(GLFW_KEY_UP) == true) 81 { 82 mVector.x = 0.0f; 83 mVector.y = 1.0f; 84 mKeyCode = Key_Code::Up; 85 86 } 87 else if (mInput->KeyDownHold(GLFW_KEY_DOWN) == true) 88 { 89 mVector.x = 0.0f; 90 mVector.y = -1.0f; 91 mKeyCode = Key_Code::Down; 92 93 } 94 else { 95 mSpeed = 0; 96 } 97 98 // 攻撃 99 if (mInput->KeyDownHold(GLFW_KEY_SPACE) == true) 100 { 101 bullet.push_back(Bullet(Owner, mPosition, mVector)); 102 } 103 104 105 // 弾 更新 106 for (std::vector<Bullet>::iterator itr = bullet.begin(); itr != bullet.end(); ) 107 { 108 itr = bullet.erase(itr); 109 } 110 mPosition += mVector * mSpeed; //実移動 111} 112 113 114// 描画 115void Player::Draw() 116{ 117 mSprite->DrawGraph(mPosition, mSpriteNum.at((int)mKeyCode).at(1).at(0), mSpriteNum.at((int)mKeyCode).at(1).at(1)); 118} 119 120 121 122 123 124 125// デストラクタ 126Player::~Player() 127{ 128 129} 130
cpp
1#include "../../Header/Game/Bullet.hpp" 2#include "../../Header/Sprite.hpp" 3 4 5 6// コンストラクタ 7Bullet::Bullet(class Game* g,glm::vec2 pos,glm::vec2 vec) : Actor_2D() 8{ 9 Owner = g; //Game クラス 10 11 mPosition = pos; //座標 12 mVector = vec; //方向 13 speed = 10; //速度 14 15 mSprite = new Sprite(g,"Assets/Bullet.png"); // スプライトクラス 16} 17 18// 計算 19void Bullet::Update() 20{ 21 mPosition.x += mVector.x * speed; 22 mPosition.y += mVector.y * speed; 23 24// printf("mPosition.x: %f\n", mPosition.x); 25// printf("mPosition.y: %f\n",mPosition.y); 26 27} 28 29// 描画 30void Bullet::Draw() 31{ 32 glm::vec2 size = mSprite->getSize(); 33 mSprite->DrawGraph(mPosition,glm::vec2(0,1),glm::vec2(size.x,size.y)); 34} 35 36 37glm::vec2 Bullet::getPosition() 38{ 39 return mPosition; 40} 41 42 43 44 45// コピーコンストラクタ 46Bullet::Bullet(const Bullet &b) 47{ 48 printf("Bullet コピーコンストラクタ\n"); 49 50 51 mPosition = b.mPosition; 52 mVector = b.mVector; 53 speed = b.speed; 54 Owner = b.Owner; 55 56 mSprite = new Sprite(b.Owner, "Assets/Bullet.png"); 57 //mSprite = b.mSprite; 58} 59 60 61// デストラクタ 62Bullet::~Bullet() 63{ 64 printf("Bullet デストラクタ\n"); 65 delete mSprite; 66 //printf("アドレス: %x\n",mSprite); 67 mSprite = nullptr; 68} 69
cpp
1#include "../Header/Sprite.hpp" 2#include "../Header/Shader.hpp" 3#include "../Header/Game.hpp" 4#include "../Header/Texture.hpp" 5#include "../Header/VertexData.hpp" 6 7// 数学ライブラリ 8#include "glm/ext.hpp" 9#include "glm/glm.hpp" 10 11// OpenCV 12#include <opencv2/core.hpp> 13 14class Game; 15/*################################################################################################################ 16* 画像 描画クラス 17################################################################################################################*/ 18 19//コンストラクタ 20/* 21* Game クラス 22* テクスチャ パス 23* 描画する画像の寸法 24*/ 25Sprite::Sprite(class Game* g, const char* FileName) : Transform_2D(g) 26{ 27 shader = new Shader(g,"Shader/2D/Sprite.vert", "Shader/2D/Sprite.frag"); 28 Owner = g;//Gameクラス 29 30 Transform_2D::setTransfrom(glm::vec2(1,1),0,glm::vec2(0,0)); //トランスフォームを初期化 31 32 //テクスチャを設定 33 glGenTextures(1, &TextureID); 34 glBindTexture(GL_TEXTURE_2D, TextureID); 35 36 float width = 0, height = 0; //画像の寸法 37 int channels = 0; //画像のチャンネル数 38 39 byte* data = LoadTexture(FileName,width,height,channels); //テクスチャを取得 40 41 42 mPicSize.x = width; 43 mPicSize.y = height; 44 45 //printf("widht: %f\n", width); 46 //printf("height: %f\n", height); 47 48 if (data != NULL) 49 { 50 if (channels == 3) 51 { 52 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)width, (GLsizei)height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 53 } 54 else if (channels == 4) 55 { 56 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 57 } 58 } 59 else { 60 std::cerr << "Unable to load texture: " << FileName << std::endl; 61 } 62 63 64 65// mSize = end - start; //画像のサイズを取得 66 67// printf("width: %.2f\n", mSize.x); 68// printf("height: %.2f\n",mSize.y); 69 70 /* 71 vertex[0] = VertexAttribute_2D{ -width / 2.0f,height / 2.0f, 0,0 }; 72 vertex[1] = VertexAttribute_2D{ -width / 2.0f,-height / 2.0f, 0,1 }; 73 vertex[2] = VertexAttribute_2D{ width / 2.0f,-height / 2.0f, 1,1 }; 74 75 vertex[3] = VertexAttribute_2D{ -width / 2.0f,height / 2.0f, 0,0 }; 76 vertex[4] = VertexAttribute_2D{ width / 2.0f,-height / 2.0f, 1,1 }; 77 vertex[5] = VertexAttribute_2D{ width / 2.0f,height / 2.0f, 1,0 }; 78 */ 79 80 81 /* 82 * 83 // 頂点情報を設定 84 vertex[0] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f, start.x * uvWidth,start.y * uvHeight }; 85 vertex[1] = VertexAttribute_2D{ -mSize.x / 2.0f,-mSize.y / 2.0f, start.x * uvWidth,end.y * uvHeight }; 86 vertex[2] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f, end.x * uvWidth,end.y * uvHeight }; 87 88 vertex[3] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f, start.x * uvWidth,start.y * uvHeight }; 89 vertex[4] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f, end.x * uvWidth,end.y * uvHeight }; 90 vertex[5] = VertexAttribute_2D{ mSize.x / 2.0f,mSize.y / 2.0f, end.x * uvWidth,start.y * uvHeight }; 91 92 */ 93 94 95 //VAO 96 97 98 //ミニマップを設定 99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 101 glGenerateMipmap(GL_TEXTURE_2D); 102 103 //異方性フィルタリングを設定 104 GLfloat largest; 105 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest); 106 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest); 107 108 109 110 111 delete data; 112 data = nullptr; 113} 114 115//描画 116void Sprite::DrawGraph(glm::vec2 pos, glm::vec2 start, glm::vec2 end) 117{ 118 119 120 Transform_2D::UpdateTransform(); //トランスフォームを更新 121 Transform_2D::setTransform_Move(pos); //移動 122 123 shader->Enable(); //シェーダーを有効にする 124 shader->SetFloatUniform_3m("uViewMatrix", getViewMatrix()); 125 shader->SetFloatUniform_3m("uWorldMatrix", getWorldMatrix()); 126 127 128 glm::vec2 mSize; 129 mSize = end - start; //画像のサイズを取得 130// printf("mSize.x %f\n", mSize.x); 131//` printf("start.x. x%f\n", end.x); 132 133 134 135 136 // 頂点情報を設定 137 vertex[0] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f, start.x / mPicSize.x ,start.y / mPicSize.y }; 138 139// printf("%f\n", start.y / mSize.y); 140 141 vertex[1] = VertexAttribute_2D{ -mSize.x / 2.0f,-mSize.y / 2.0f, start.x / mPicSize.x ,end.y / mPicSize.y }; 142 vertex[2] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f, end.x / mPicSize.x ,end.y / mPicSize.y }; 143 144 vertex[3] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f, start.x / mPicSize.x ,start.y / mPicSize.y }; 145 vertex[4] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f, end.x / mPicSize.x ,end.y / mPicSize.y }; 146 vertex[5] = VertexAttribute_2D{ mSize.x / 2.0f,mSize.y / 2.0f, end.x / mPicSize.x ,start.y / mPicSize.y }; 147 148 149 150 //VAO 151 glGenVertexArrays(1, &VAO); 152 glBindVertexArray(VAO); 153 154 //VBO 155 glGenBuffers(1, &VBO); 156 glBindBuffer(GL_ARRAY_BUFFER, VBO); 157 glBufferData(GL_ARRAY_BUFFER, (sizeof(vertex) / sizeof(vertex[0])) * sizeof(VertexAttribute_2D), vertex, GL_STATIC_DRAW); 158 159 //頂点座標 160 glEnableVertexAttribArray(0); 161 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), NULL); 162 163 //UV座標 164 glEnableVertexAttribArray(1); 165 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), (void*)(sizeof(float) * 2)); 166 167 168 glBindVertexArray(VAO); 169 glBindTexture(GL_TEXTURE_2D, TextureID); 170 glDrawArrays(GL_TRIANGLES, 0, (GLsizei)std::size(vertex)); 171 172 // バッファを解放 173 glDeleteBuffers(1,&VAO); 174 glDeleteVertexArrays(1,&VAO); 175 176 glBindVertexArray(0); 177 glBindTexture(GL_TEXTURE_2D, 0); 178 179} 180 181 182// 画像サイズを取得 183glm::vec2 Sprite::getSize() 184{ 185 return mPicSize; 186}
GitHub全文ソースを追加しました。
アクセスエラーになるのはBulletをvectorに入れていることが原因で間違いないのですか? Bulletはそもそもコピー可能にしてよい概念ですか?
bullet変数に代入していいのですがだめなのでしょうか?一つ一つprintf();しましたがどこが原因でどうなっているのか理解出来ませんw
結局mSpriteの破棄時にエラーなのですか?開発環境も提示されていないので、スペースカチカチで何をしているか把握できる人はいないかと。
文章と提示コードを修正しました。
あれ? アクセスエラーの問題はどうなったんでしょうか? メモリリークはどうやって確認して何のオブジェクトがリークしているのですか?
std::vector<Bullet> bullet変数で起きてます。しっかり.erase()しているのにも関わらずメモリリークしている理由はんでしょうか?
他にも解放出来ていないからでしょう。
診断ツールを使えば、どこで確保されたメモリがリークしているかわかりますよね。それを開示してください。で、この質問の当初のアクセスエラーの問題は解決したのですか?
いえ、メモリリークでアクセスエラーが起きてました。主原因がメモリリークだったのでこっちにしました。
Sprite クラスを追加
Spriteのクラス宣言全体とデストラクタの定義も掲載してください。
回答3件
あなたの回答
tips
プレビュー