C++ I';m创建DirectX 10缓冲区时内存泄漏

C++ I';m创建DirectX 10缓冲区时内存泄漏,c++,memory-leaks,directx,C++,Memory Leaks,Directx,我有一个简单的渲染过程,将一组顶点发送到几何体着色器,并根据该信息渲染精灵 这个小应用程序的内存使用率达到了顶峰,不断增加。我用\u crtdumpmomeryleaks()和可视泄漏检测器进行了快速测试,它们都声称没有泄漏 我有一个设备和一个装满顶点信息的容器: ID3D10Device* pD3DDevice; std::vector<SpriteVertex>* sprites; 我不确定要在每个帧上释放或删除什么才能停止此操作。每次成功调用ID3D10Device::Cre

我有一个简单的渲染过程,将一组顶点发送到几何体着色器,并根据该信息渲染精灵

这个小应用程序的内存使用率达到了顶峰,不断增加。我用
\u crtdumpmomeryleaks()
和可视泄漏检测器进行了快速测试,它们都声称没有泄漏

我有一个设备和一个装满顶点信息的容器:

ID3D10Device* pD3DDevice;
std::vector<SpriteVertex>* sprites;

我不确定要在每个帧上释放或删除什么才能停止此操作。

每次成功调用ID3D10Device::CreateBuffer都需要与调用release()相匹配。

正如Tom所说,创建缓冲区后需要释放缓冲区。 然而,我认为在渲染函数中创建缓冲区不是一件好事。 这意味着您每次都在一次又一次地创建缓冲区。这不仅是内存泄漏,而且速度非常慢,不需要

所以只需创建一个初始化函数来创建缓冲区。还可以创建一个函数,在不再需要缓冲区时(在场景结束时)释放缓冲区。然后,render函数应该只包含对缓冲区绘图的调用

希望这对你有所帮助


祝你好运

由于其他答案假设解决方案很快,而且评论有点太短,所以又是一个快速回答您询问在运行时更新创建的缓冲区还需要什么:

您可以将缓冲区使用情况从
D3D10\u使用情况\u默认值
(GPU只读/写)更改为
D3D10\u使用情况\u动态
,从而使
CopySubResource()
CopySubresourceRegion()
等功能正常工作。您可以更新部分或整个缓冲区,等等。这会对性能产生一些影响,但这是意料之中的,因为在初始化常量缓冲区时,动态的成本固有地高于静态的成本。我会避免说太多的技术细节,把调查的乐趣留给你

关于开头问题的冗长回答 Yarrr,我衷心感谢,新数据。还有一桶朗姆酒。 我将尝试提供更多关于“为什么”和“如何”背后的信息,但仍然保持阅读的乐趣。各种各样的网站,包括维基百科,从所有与计算机科学相关的东西中汲取乐趣。关键是让程序员直观地理解为什么,并让他分析如何回应为什么。就像数学中的一个简单概念一样,同余平行排列,对于初学者来说,听起来最多也很神秘,每单位时间会产生大量的脏话。正如我无数次证明的那样,对动机的理解有助于正确理解

内存泄漏问题是由于您没有像其他人所说的那样正确管理内存。通常,一个很好的指标是你是否需要担心内存(当经典的C/C++指标不能像new、delete、malloc等那样运行时),你是否有一个指向微软源代码中任何东西的指针(通常是COM接口,它可以调解你和底层COM组件实例之间的协商,或者,如果你愿意,COM对象)。这还包括你不完全理解的其他API,它们是由你不认识的人开发的。但是,让我们先谈谈COM和其中一个怪癖——内存管理。实际上,它很简单,如果你采用特殊的创建/初始化方法,它就不能与经典C++对象有很大区别。 虽然缓冲区本身没有手动分配(目前的情况),但至少以经典的C/C++方式,任何在符合COM的接口上运行并使指向这些接口的初始空指针工作的东西都很可能依赖于您调用
Release()
完成后,该功能将正常运行

Release()
是对
delete
关键词的直接翻译,我们都学会了珍惜和爱。因此,是的,请确保您遵循Microsoft的指令,通过查询各种创建函数(构造函数的等价物)来管理您获取的COM对象,这些函数将使用实际初始化的COM组件实例或对象的地址填充接口指针。为了将来参考和满足好奇心,每个COM接口都源于
IUnknown
,它提供了
Release()

为什么对COM大惊小怪? [P>微软API是一种基于COM(组件对象模型)的实现方法,是实现普通C++接口驱动代码的方法,在纯C++中,抽象类和快乐的时间由VTABLE和继承驱动,这驱动了多态性的概念。但是,你一定很好奇为什么根本不使用C++?你看,DirectX在COM第一次推出的时候就已经很老了(想想1994/1995年吧),它是COM基本理念的自然选择

最初,COM的开发是为了帮助跨工具协作(Microsoft Office suite),或者更专业地帮助进程间通信。在这个篮子里,你也可以放下OLE。从这一点上,微软的软件工程师看到了进一步扩展这一功能的潜力。该推理主张以COM组件的形式创建各种资源,该组件将响应可通过COM组件首次出现以解决问题的语言访问的标准化接口。这样,微软就可以将他们的大量工作封装在一个可伸缩的formfactor中,为其分配各种唯一标识符(uuuIdof(),您遇到过它,这就是COM注册/跟踪所有类的方式),制作一个跨语言的解决方案,使在其他地方按照COM规则编译的东西能够以完全不同的语言工作

void DirectX10Renderer::RenderSprites()
{
    D3D10_SUBRESOURCE_DATA initData;
    initData.pSysMem = &((*sprites)[0]);

    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof(SpriteVertex)*(numSprites);
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;

    // As soon as the following line is uncommented, memory starts leaking
    pD3DDevice->CreateBuffer(&bd, &initData, &m_SpriteBuffer)); // <-- this is leaking

    // the rest of the rendering code is for now commented out
}