gpt4 book ai didi

c++ - SDL 2.0 内存泄漏

转载 作者:行者123 更新时间:2023-11-28 00:01:24 26 4
gpt4 key购买 nike

所以我的 SDL2.0 程序有内存泄漏我设法把它归结为这段代码,我不知道我是不是瞎了,但有人能看看他们是否能看到这里的内存泄漏吗?

我感谢所有回复的人。

SDL_Color colour = { 255,255,255 };

SDL_Surface* surfaceMessage = nullptr;

SDL_Texture* Message = nullptr;

for (int i = 0; i < m_vItems.size(); i++)
{
if (surfaceMessage != nullptr)
{
SDL_FreeSurface(surfaceMessage);
}

SDL_Color colour = {255,255,255};
if (i == m_iSelection)
{
colour = { 255,0,0 };
}

surfaceMessage = TTF_RenderText_Solid(m_Font, m_vItems[i].c_str(), colour); // as TTF_RenderText_Solid could only be used on SDL_Surface then you have to create the surface first

Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); //now you can convert it into a texture


//Get split change
float thing = screenHeight - 2 * (screenHeight* 0.3);
thing /= m_vItems.size();

SDL_Rect Message_rect; //create a rect
Message_rect.x = m_iPosX; //controls the rect's x coordinate
Message_rect.y = m_iPosY + (i * thing); // controls the rect's y coordinte
Message_rect.w = 0.18* screenWidth; // controls the width of the rect
Message_rect.h = 0.08 * screenHeight; // controls the height of the rect

SDL_RenderCopy(renderer, Message, NULL, &Message_rect); //you put the renderer's name first, the Message, the crop size(you can ignore this if you don't want to dabble with cropping), and the rect which is the size and coordinate of your texture
}

if (surfaceMessage != nullptr)
{
SDL_FreeSurface(surfaceMessage);
}

最佳答案

纹理需要用 SDL_DestroyTexture 销毁功能,而您没有这样做,这会导致内存泄漏。

顺便说一下,当你不再需要它时手动调用原始指针上的销毁函数很容易出错(你很容易忘记它需要去哪里)并且没有必要,Resource Acquisition Is初始化 (RAII)

确保正确处理获取的资源实际上是 C++ 中的一项相当普遍的要求,而且它非常适合。您可以使用 RAII 获取对象生命周期来为您管理资源,它让您在类的析构函数中放置销毁/解除分配代码,因此当管理资源的对象超出范围时,它会自动执行。这也使异常安全变得容易,因为即使在发生异常的情况下也会执行析构函数代码。

在你的例子中,你有一个类存储一个指向创建的 SDL 对象的指针,然后为你在析构函数中管理的各种对象调用相关的 SDL 生命周期结束函数,所以纹理管理类可能看起来像:

class Texture{
SDL_Texture* texture_;
public:
// or simply pass the arguments for texture creation in and create it internally
Texture(SDL_Texture* texture) : texture_{texture}{}
~Texture(){
if (texture_ != nullptr){
SDL_DestroyTexture(texture_);
}
}

// ... functions to access texture
};

但是请注意,您实际上是在包装一个指向具有非典型生命周期结束要求的资源的指针,并且这些要求本质上是调用一个将指针作为参数的自由函数,前提是它不是空指针。

你不需要创建一个特定的类来做这件事——unique_ptr 是为这个工作设计的,如果你给它一个自定义删除器,它会做得很好.为 unique_ptr 提供自定义删除器也是一项简单的任务。1

如果你有一个函数,它接受一个指针类型 T* 作为它唯一的参数,并结束指向对象和相关内存的生命周期,它就像这样简单:

#include <memory>

void shoutFooDestruction(Foo* foo); // my special lifetime ending function

int main(){
std::unique_ptr<Foo, decltype(&shoutFooDestruction)> ptr{
new Foo(),
shoutFooDestruction};
ptr.reset(new Foo());
}

这将调用 shoutFooDestruction 两次:一次是针对在其生命周期开始时赋予唯一指针的原始指针,另一次是在 unique_ptr重置时调用,一次用于重置时提供的 Foo,当 unique_pointer 的生命周期在 main 结束时结束。2

See it live on Coliru

SDL_Texture 的等价物是:

std::unique_ptr<SDL_Texture, &SDL_DestroyTexture> message{
nullptr,
SDL_DestroyTexture};

对于 SDL_Surface:

std::unique_ptr<SDL_Surface, &SDL_FreeSurface> surfaceMessage{
nullptr,
SDL_FreeSurface};

当您需要来自 SDL 的新纹理或表面时,您可以在唯一指针上调用 reset,它们会为您处理任何旧纹理或表面。当 unique_ptr 超出范围时,将使用相同的函数处理函数末尾 unique_ptr 的任何剩余内容。


1。如构造函数 3 和 4 中所示 on cppreference's page on constructors for unique pointers

2。在具有 nullptr 值的唯一指针上调用 reset will not call the provided deleter unique_ptr's destructor也是如此,因此如果您没有要删除的内容,则无需担心避免删除调用。

关于c++ - SDL 2.0 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38728023/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com