Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++/SDL内存管理_C++_Memory_Sdl - Fatal编程技术网

C++ C++/SDL内存管理

C++ C++/SDL内存管理,c++,memory,sdl,C++,Memory,Sdl,我在做一个简单的滚动太空射击游戏。我有一个由实体类对象继承的Sprite类。这些对象有内存泄漏。我用这个游戏的主菜单测试了这个,我相信问题出在精灵类中 内存的问题似乎是我没有SDL_销毁纹理和渲染器。然而,通过破坏纹理,我得到了一个纹理被另一个纹理替代的结果,或者根本没有纹理。如果破坏渲染器,则不会加载任何图像。如果我两个都没有破坏,那么所有的东西都可以加载,但是内存泄漏了 我相信野生纹理与我处理对象向量的方式有关,但我不知道还有其他方式来处理它们 精灵类: Sprite::Sprite() {

我在做一个简单的滚动太空射击游戏。我有一个由实体类对象继承的Sprite类。这些对象有内存泄漏。我用这个游戏的主菜单测试了这个,我相信问题出在精灵类中

内存的问题似乎是我没有SDL_销毁纹理和渲染器。然而,通过破坏纹理,我得到了一个纹理被另一个纹理替代的结果,或者根本没有纹理。如果破坏渲染器,则不会加载任何图像。如果我两个都没有破坏,那么所有的东西都可以加载,但是内存泄漏了

我相信野生纹理与我处理对象向量的方式有关,但我不知道还有其他方式来处理它们

精灵类:

Sprite::Sprite()
{
}

Sprite::Sprite(SDL_Renderer* pRenderer, std::string filePath, int x, int y, int w, int h)
{
_renderer = pRenderer;
_filePath = filePath;

_image = IMG_LoadTexture(_renderer, filePath.c_str());

_rect.x = x;
_rect.y = y;
_rect.w = w;
_rect.h = h;
}

Sprite::~Sprite()
{
std::cout<<_filePath<<" destroyed"<<std::endl;
SDL_DestroyTexture(_image);
//SDL_DestroyRenderer(_renderer);

}
void Sprite::draw()
{
SDL_RenderCopy(_renderer, _image, NULL, &_rect);
}
小行星类只是随机改变图像的类之一。。它继承实体,而实体继承精灵。。不确定它是否也在泄漏内存。很难用其他东西来测试

以下是小行星等级:

Asteroid::Asteroid(SDL_Renderer* pRenderer) :

_health(50)
{
_renderer = pRenderer;

_posX = getRandom(800);
_posY = -50;
_width = 30;
_height = 30;

_velocityX = getRandom(2);
_velocityY = getRandom(2);

initSprite(pRenderer, "Asteroid.png", _posX, _posY, _width, _height);

 }

Asteroid::~Asteroid()
{

//EMPTY
}

bool Asteroid::update(std::vector<Bullet>& bullets,
                  std::vector<Block>& blocks)
{
//COLLISION BULLET
for (int i = 0; i < bullets.size(); i++)
{
    if (collisionCheck(bullets[i].getRect()))
    {
        //CHANGE VELOCITY & POSITION
        _velocityY -= 0.2f;

        _posY -= 3;

        //TAKE DAMAGE
        _health -= 10;
    }
}

if(_posY >= 500)
{
    return false;
}

//IF DEAD
if (_health <= 0)
{
    return false;
}

//MOVEMENT
drift();

return true;
}

void Asteroid::draw()
{
Entity::draw();
}

void Asteroid::drift()
{
//move position
_posX += _velocityX;
_posY += _velocityY;

//check boundaries
if (_posY > 0) {
    if (_posX < 0)
    {
        _velocityX *= -1;
    }
    if (_posX > 800 - _width)
    {
        _velocityX *= -1;
    }
    if (_posY < 0)
    {
     _velocityY *= -1;
    }
    if (_posY > 600 - _height)
    {
        _velocityY *= -1;
    }
}

}

bool Asteroid::collisionCheck(SDL_Rect rect2)
{
return !(_rect.x > rect2.x + rect2.w || _rect.x + _rect.w < rect2.x ||
         _rect.y > rect2.y + rect2.h || _rect.y + _rect.h < rect2.y );
}

int Asteroid::getRandom(int threshold)
{
 _randomNumber = rand() % threshold + 1;

return _randomNumber;}
小行星:小行星(SDL_渲染器*pRenderer): _卫生(50) { _渲染器=pRenderer; _posX=getRandom(800); _posY=-50; _宽度=30; _高度=30; _velocityX=getRandom(2); _velocityY=getRandom(2); initSprite(pRenderer,“Asteroid.png”,_posX,_posY,_width,_height); } 小行星::~小行星() { //空的 } 布尔小行星::更新(标准::矢量和子弹, 标准:向量和块) { //碰撞弹 对于(int i=0;i=500) { 返回false; } //如果死了 如果(_运行状况0){ 如果(_posX<0) { _速度x*=-1; } 如果(_posX>800-_宽度) { _速度x*=-1; } 如果(_posY<0) { _速度y*=-1; } 如果(\u位置>600-\u高度) { _速度y*=-1; } } } 布尔小行星::碰撞检查(SDL_Rect rect2) { return!(_rect.x>rect2.x+rect2.w | | | | rect.x+_rect.wrect2.y+rect2.h | | | u rect.y+_rect.h 我刚到C++,但学习快。如果有人能给我指出正确的方向,我将不胜感激


谢谢

问题在于向量直接存储对象。因此,当对象被复制/移动时,它们将在不应该的情况下破坏纹理

例如,我假设您尚未实现自定义副本构造函数。。。假设您有一个
std::vector
,您正试图向其中添加一个新对象,如下所示:

{
  Sprite s(renderer, "image.png", 0, 0, 100, 100);
  sprites.push_back(s);
}
执行此操作时,
s
将加载纹理。当您将其推到
精灵
向量上时,它将创建
s
的副本(因此现在它们都具有相同的
\u图像
值)。然后在下一行(当
s
超出范围时),
s
将破坏纹理-
精灵
向量中的副本仍在尝试引用它

与其拥有对象本身的向量,不如尝试将
std::shared_ptr
s作为向量。像这样:

std::vector<std::shared_ptr<Sprite> > sprites;
std::shared_ptr<Sprite> s(new Sprite(renderer, "image.png", 0, 0, 100, 100));
sprites.push_back(s);
std::矢量精灵;
std::shared_ptr s(新的Sprite(渲染器,“image.png”,0,01000));
精灵。向后推_(s);
这样,只复制指针,并且只有一个真实对象(当没有人引用它时,它将被自动删除)


查看文档以了解更多信息。

堆栈溢出新增功能。。对不起,我的邮件重复了。。这就是我想说的:我肯定会研究共享指针,但我将使用emplace_向向量添加对象,并为每个对象提供它自己的值。idk,如果这有什么不同。。实际上,我已经用纹理管理器类“解决”了这个问题,但我仍然不能100%确定。。当你说只有一个真实对象,而其他所有对象都引用它时,这与纹理/资源管理器类似吗?如何引用一个对象,但让它同时占据多个位置?即使使用emplace_向后添加对象,当向量增大/缩小时,它也会复制包含的对象。如何引用该对象?例如与射弹的碰撞。现在,我将向量传递到函数中,但到目前为止,我无法使用shared_ptr实现这一点
std::vector<std::shared_ptr<Sprite> > sprites;
std::shared_ptr<Sprite> s(new Sprite(renderer, "image.png", 0, 0, 100, 100));
sprites.push_back(s);