0

This class ctor is leaking memory, I cant say what is going on. How I know? If I comment out the second ctor line, the leak goes away.

template< class T, int fixedSize >
class Resource_Cache{

private:

    ID3D11Device * m_pDeviceRef;    // the one that actually can create stuff

    UINT m_iCurrentIndex;           // next slot to be allocated, also the ID of the resources
    //UINT m_nFreedSlots;               // how many freed slot there are?

    T* m_cache[fixedSize];          // the container per se

    struct SlotInfo{

        UINT nUseCount;
        Resource_Descriptor<T> desc;

    } m_slotsInfo[fixedSize];//use a hashtable<desc,index on m_cache>;


    Resource_Cache();   //denied default ctor

public:

    Resource_Cache( ID3D11Device * pDevice_p ): m_pDeviceRef(pDevice_p), m_iCurrentIndex(0){

        memset(m_cache, NULL, fixedSize*sizeof(T*));
        memset( m_slotsInfo, 0, fixedSize*sizeof(SlotInfo));    // zero slotsInfo memory(CAUSING LEAKS)
    }
 ...

Might be simple stuff, but Im clueless..

  • EDIT TO ANSWER - As PermanentGuest said: No. It doesn't give problems for elementary types. But, if your type T of Resource_Descriptor has some implementation which allocates memory in the constructor(e.g, string) by memset, you would be resetting any internal pointers of that class to NULL, thereby denying its destructor a chance to delete the memory. – PermanentGuest

std::string was the problem, solved.

Icebone1000
  • 1,231
  • 4
  • 13
  • 25
  • 3
    A `memset` won't cause a "leak" on its own. What is `Resource_Descriptor` exactly? – user7116 Jul 24 '12 at 13:52
  • 3
    How did you deduce you have a leak? – sharptooth Jul 24 '12 at 13:52
  • How do you instantiate Resource_Cache? on heap or stack? – PermanentGuest Jul 24 '12 at 13:54
  • @sixlettervariables: Resource_Descriptor is a empty class, where I provide a specialization for T for each resource...I know its not a clean approach, but is what I have now.. – Icebone1000 Jul 24 '12 at 13:59
  • BTW, theres NO Resource_Descriptor class allocating memory at constructor! – Icebone1000 Jul 24 '12 at 14:02
  • @sharptooth vs 2010 output, Im using that crazy #ifdef _DEBUG _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );//? #endif call, I always use it so Im not sure if it is this who is warning me or its the default behaviour. – Icebone1000 Jul 24 '12 at 14:04
  • @Icebone1000: What is the specialization of T for Resource_Descriptor when you have this leak? – PermanentGuest Jul 24 '12 at 14:04
  • @PermanentGuest: I tried all of them, all of them gave me leaks, at first I was declaring all ones possible inside that class, but when I was isolating the problem I figured out all of them gave me leaks. – Icebone1000 Jul 24 '12 at 14:07
  • 2
    @Icebone1000: No. It doesn't give problems for elementary types. But, if your type T of Resource_Descriptor has some implementation which allocates memory in the constructor(e.g, string) by memset, you would be resetting any internal pointers of that class to NULL, thereby denying its destructor a chance to delete the memory. – PermanentGuest Jul 24 '12 at 14:10
  • @PermanentGuest: DAMN! Already have problems like that in the past, why my brain doesnt hold stuff like that..see, using stl to me is always the problem, not the solution..std::string was a head shot. – Icebone1000 Jul 24 '12 at 14:18
  • possible duplicate of [Using memset on structures in C++](http://stackoverflow.com/questions/2773927/using-memset-on-structures-in-c) – Bo Persson Jul 24 '12 at 14:19
  • @Icebone1000: stl string would **definitely** give this problem as it preallocates buffers. Please see the answers below. As far as you don't mix-up C with C++, STL wouldn't give as many problems as you describe... – PermanentGuest Jul 24 '12 at 14:21

1 Answers1

1

Instead of

Resource_Cache( ID3D11Device * pDevice_p ): m_pDeviceRef(pDevice_p), m_iCurrentIndex(0){

        memset(m_cache, NULL, fixedSize*sizeof(T*));
        memset( m_slotsInfo, 0, fixedSize*sizeof(SlotInfo));    // zero slotsInfo memory(CAUSING LEAKS)
    }

do

Resource_Cache( ID3D11Device * pDevice_p )
    : m_pDeviceRef( pDevice_p )
    , m_iCurrentIndex()
    , m_cache()
    , m_slotsInfo()
{}

I'm pretty sure this will not cure the symptoms that you conclude are due to a memory leak, or the memory leak if there is one, but at least it eliminates the possible cause you've fixated on, by doing the zeroing in (safe) C++ instead of (unsafe) C.

Oh well, because of the unspecified not-described-at-all Resource_Descriptor<T> it might actually fix the problem. But you wouldn't be using memset if that wasn't a POD, now would you? Or, perhaps you would?

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 1
    Isn't the constructors of m_cache etc called automatically? Why the initialization list needed at all? – PermanentGuest Jul 24 '12 at 14:19
  • 1
    m_cache and m_slostInfo are arrays, whats m_cache()/m_slostInfo() is doing? – Icebone1000 Jul 24 '12 at 14:24
  • @PermanentGuest: `m_cache` is a raw array of raw pointers, i.e. it's a POD. it doesn't have constructors. in the name of efficiency, C++ lets it be uninitialized by default. – Cheers and hth. - Alf Jul 24 '12 at 17:41
  • @Icebone1000: quoting the answer you commented on, "doing the zeroing in (safe) C++ instead of (unsafe) C". it's a good idea to read what you comment on, before you comment on it. – Cheers and hth. - Alf Jul 24 '12 at 17:42
  • @downvoter: please explain your insight so that others can benefit from it, either that they learn something new about c++ or about you. – Cheers and hth. - Alf Jul 24 '12 at 17:42
  • @Cheersandhth.-Alf the question was how the questioner could find out what was going wrong. He already noticed that passing on the second memset is a solution. Anyway, my downvote might be bit harsh, but I cannot remove it unless the answer is edited. Using the information from the comments and making the last paragraph not contradictory to the previous might be a worth an edit. Will you or should I? – Arne Jul 25 '12 at 09:04
  • @Arne: It's okay. As you note it turned out the OP was indeed `memset`tting a non-POD, so that my answer, contrary to my belief, would also be fix for the stated problem. I wouldn't edit the answer because there's a great subtlety here (C++03 default initialization versus C++11 value initialization), plus, depending on how the OP has "fixed" the problem, the possibility of a violation of the rule of three, and the OP doesn't describe he's done. And anyway the last paragraph is not contradictory. As stated, I didn't believe he did what we now know he did, but if so, my answer was (is) a fix. – Cheers and hth. - Alf Jul 25 '12 at 20:58