这是一个C ++内存管理问题,因此我选择在这里提问。 我正在用SFML创建一个游戏。我之前使用过SDL并且管理我的Textures非常简单,但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*/
我遇到的挑战是在Sprite图像的Character类中使用sf :: Texture会导致绘制一个白色矩形。因此,字符精灵失去了纹理链接,而SFML只是绘制了一个白色矩形。为了解决这个问题,我创建了一个原始纹理指针并在Character构造函数中初始化它。这样可以正确地绘制Sprite。
//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
这将绘制一个漂亮的海军蓝黑色矩形而不是精灵纹理。我不知道如何或者我是否可以声明然后再初始化unique_ptr。
我认为我正在泄漏内存,如果是这样,我如何正确使用智能指针或正确管理自己的内存?
我添加了一些细节和代码,因为我意识到我很模糊。此外,我正在查询纹理并使用它来设置Sprite Rect维度,因此它肯定被加载,但为了安全起见,我有一个记录器函数来检查我调用的任何资源是否已加载。
答案 0 :(得分:2)
如果sf::Texture
是Character
的成员,那么在<{1}}实例发布之前,不将超出范围。
使用调试器断点来跟踪发生的情况。在Character
和Character
的析构函数中抛出一个断点,然后遍历启动和关闭序列。或使用Log打印消息,如:“Character :: ~call。”
我认为我正在泄漏内存,如果是这样,我如何正确使用智能指针或正确管理自己的内存?
对所有假设进行质询,包括正在正确加载纹理的假设。直到您在屏幕上看到纹理绘制,您没有证据表明您已加载它。 (除非你想要一个深蓝色的矩形。我不知道你想要绘制什么。我假设一个角色精灵。)
来自SFML文档:
loadFromFile函数有时会失败,没有明显的原因。首先,检查SFML打印到标准输出的错误消息(检查控制台)。如果消息无法打开文件,请确保工作目录(任何文件路径将被解释为相关的目录)是您认为的:当您从桌面环境运行应用程序时,工作目录是可执行文件夹。但是,当您从IDE(Visual Studio,Code :: Blocks,...)启动程序时,工作目录有时可能会设置为项目目录。这通常可以在项目设置中轻松更改。
直到您看到泄漏检测器发生泄漏,您才真正无法假设您正在泄漏内存。您可以在程序中添加第三方内存跟踪器。
再次,在sf::Texture
析构函数中使用调试断点来停止执行,并确切地查看解除分配的位置(如果这是问题)。
你真的应该阅读并关注Minimal, Complete, and Verifiable example。就我们所知,你可以做这样的事情:
sf::Texture
错误很明显。