C ++ с D3DX9 - Объем памяти продолжает увеличиваться со скоростью 10 МБ / с - Почему? - PullRequest
1 голос
/ 13 декабря 2010

Я работаю над 3D движком как школьный проект. Я установил виртуальный детектор утечек, чтобы избавиться от утечек памяти (и это сработало, поскольку я больше не получаю ни одного из этих дампов). Недавно я случайно оставил приложение запущенным на 5 минут ... И мой компьютер стал чертовски медленным. Я разыскал проблему, закомментировав строки и тому подобное, но не могу понять, почему C ++ не освободит мою очищенную память, пока я не закрою приложение.

ПРОБЛЕМА: «Внутренняя» утечка памяти, похоже, что C ++ удаляет что-то только после закрытия приложения

КОД: Мой код рендеринга (на пастбине Yz79Ck0b)

ПРИМЕЧАНИЯ: Я знаю, что не должен каждый раз создавать новую сетку, но это не должно вызывать этой проблемы, верно? Моя IDE - Visual Studio 2008, и я использую проект WIN32. Когда я вынимаю текстуру и модель, у меня 0 байт памяти.

Ответы [ 3 ]

6 голосов
/ 13 декабря 2010

Как говорит Sanjit, вы должны использовать delete[] для удаления массивов - и, как говорит DeadMG, контейнер RAII - это лучший способ не испортить освобождение вашего ресурса.

Однако, хотя это неиз документов сразу видно, что все ресурсы Direct3d (включая IDirect3d9Texture, которые D3DXCreateTextureFromFile создает) наследуются от IUnknown - это COM-объекты, другими словами.Вам нужно .Release() COM-объектов, когда вы закончите их использовать:

for (int i=0; i<len; i++)
  if (m_Texture[i] != NULL)
    m_Texture[i]->Release();//decrement COM refcount to permit releasing the resource
delete[] m_Texture;
delete[] m_Material;

Возможно, вы захотите использовать эту повторяющуюся логику в удобном контейнере RAII.ATL имеет такую ​​встроенную функцию, см. Документацию MSDN по CComPtr.Предостережение: я никогда не использовал его раньше, но что-то вроде этого очень хорошая идея, если вы собираетесь писать что-то большее, чем игрушечное приложение, используя COM.

2 голосов
/ 13 декабря 2010

m_Material - это массив, вам нужно [] с оператором удаления:

delete[] m_Material;

Кроме того, похоже, что m_Texture является массивом новых указателей. D3DXCreateTextureFromFileA (m_Device, d3dxMaterials [i] .pTextureFilename, & m_Texture [i])

Правильный способ удаления массива динамически размещаемых указателей:

    for (int i=0; i<len; i++)
    {
      // first delete memory for each index
      if (m_Texture[i] != NULL)
      {
        delete m_Texture[i];
      }
    }

    // then delete the array
    delete[] m_Texture;
1 голос
/ 13 декабря 2010

Вам необходимо использовать RAII для обработки любых ресурсов, которые необходимо освободить, а НЕ освобождать их вручную.

template<typename T> class self_release_ptr {
    T* ptr;
public:
    self_release_ptr(T* newptr) : ptr(newptr) {}
    self_release_ptr() : ptr(0) {}
    ~self_release_ptr() { if (ptr) ptr->Release(); }
    // etc
};
std::vector<self_release_ptr<texture_type>> m_Texture;

Я мог бы быть более конкретным, но мне нужно увидеть определение классов.

...