这是一个C ++内存管理问题,因此我选择在这里询问。
我正在用SFML创建游戏。我以前使用过SDL,并且管理纹理非常简单,但是SFML的工作方式却有所不同。

我的项目设置是这样的:

class Game
//create window and initialize game stuff

class Character
/*initializes its own textures and is also responsible for updating itself
as well as drawing itself*/

int main()
/*create an instance of Game -> Create an instance of Character and
runGame. I will implement the drawing and updating properly when I
implement a scene graph and scene nodes but for now updating and drawing is
done via global functions called by the Game Class*/


我面临的挑战是,在Character类中为Sprite图像使用sf :: Texture会导致绘制白色矩形。因此,角色精灵会丢失其纹理链接,而SFML只会绘制一个白色矩形。为了解决这个问题,我创建了一个原始的Texture指针,并在Character构造函数中对其进行了初始化。这可以正常工作,并且精灵绘制正确。

//inside character.hpp
sf::Texture *texture;

//in Character constructor
texture= new (sf::Texture);


这意味着我必须管理内存,并且代码很难看。

我试图这样做来管理分配的内存(我认为)以防止内存泄漏:

Character::~Character()
{ delete texturePtr; }


但这显然是错误的。
当我退出应用程序时,我也尝试删除main。)末尾的character.Texture,但这也会导致错误。

然后,我尝试在Character构造函数内使用uinque_ptr:

std::unique_ptr<sf::Texture> texture(new sf::Texture);
//load Texture from Resource Manager instance


这会绘制一个漂亮的海军蓝黑色矩形,而不是Sprite Texture。我不确定如何或是否可以声明然后在以后初始化unique_ptr。

我认为我正在泄漏内存,如果是这样,如何正确使用智能指针或正确管理自己的内存?

当我意识到自己含糊不清时,我添加了更多细节和代码。另外,我正在查询纹理并使用它来设置Sprite Rect尺寸,因此肯定可以加载它,但是为了安全起见,我有一个记录器功能,可以检查是否调用了我调用的任何资源。

最佳答案

如果sf::TextureCharacter的成员,则它不会超出范围,直到您的Character实例包括。

使用调试器断点来跟踪发生的情况。在Charactersf::Texture的析构函数中抛出一个断点,并逐步执行启动和关闭序列。或使用Log打印消息,例如:“ Character ::〜被调用”。




  我认为我正在泄漏内存,如果是这样,如何正确使用智能指针或正确管理自己的内存?


质疑所有假设,包括您正确加载纹理的假设。在屏幕上看到纹理绘制之前,您没有证据证明已加载纹理。 (除非您想要一个海军蓝色的矩形。我不知道您要绘制什么。我假设是一个角色精灵。)

从SFML文档:


  loadFromFile函数有时可能会由于没有明显原因而失败。首先,检查SFML打印到标准输出的错误消息(检查控制台)。如果消息无法打开文件,请确保您认为工作目录(该目录是任何文件路径都将相对于的目录):从桌面环境运行应用程序时,工作目录是可执行文件夹。但是,当您从IDE(Visual Studio,代码:: Blocks,...)启动程序时,有时可能会将工作目录设置为项目目录。通常可以在项目设置中轻松更改此设置。


除非您在泄漏检测器中看到泄漏,否则您实际上无法假定您正在泄漏内存。您可以将第3方记忆跟踪器添加到程序中。

再次,使用sf::Texture析构函数中的调试断点停止执行,并确切查看要分配的位置(如果事实证明是问题所在)。



您确实应该阅读并遵循Minimal, Complete, and Verifiable example。就我们所知,您可能正在做这样的事情:

class Character{
    sf::Sprite mySprite;

    public:
    Character(){
        sf::texture aTex;
        aTex.loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png");

        mySprite.setTexture(aTex);
    }
}

// attempt 2
class Character{
    sf::Sprite mySprite;

    public:
    Character(){
        std::unique_ptr<sf::Texture> texture(new sf::Texture);
        texture->loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png");

        mySprite.setTexture(*texture);
    }
}


错误将是显而易见的。

关于c++ - SFML纹理内存管理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44225204/

10-11 22:42
查看更多