0

My program is crashing due to a exception access violation. It happens consistently when the cache gets full and starts shifting. Whats the issue with this code?

My program is crashing due to a exception access violation. It happens consistently when the cache gets full and starts shifting. Whats the issue with this code?

enter image description here

#include "TopologyOwnersManagerCache.h"

#include <iostream>
using namespace std;

TopologyOwnersManagerCache::TopologyOwnersManagerCache()
{
    m_cacheSize = 10;
    m_cacheEmptyIndex = 0;
    m_ownersManagers = new A3DTopoItemOwnersManager *[m_cacheSize];
    m_brepItems = new A3DRiRepresentationItem *[m_cacheSize];

    for (int i = 0; i < m_cacheSize; i++)
    {
        m_ownersManagers[i] = (A3DTopoItemOwnersManager *)0;
        m_brepItems[i] = (A3DRiRepresentationItem *)0;
    }
}


TopologyOwnersManagerCache::~TopologyOwnersManagerCache()
{
    for (int i=0; i < m_cacheSize; i++)
    {
        if (m_ownersManagers[i])
        {
            // Release the map
            A3DTopoItemOwnersManagerGet((A3DRiRepresentationItem *)0, m_ownersManagers[i]);
        }
    }

    delete[] m_ownersManagers;
    delete[] m_brepItems;
}


A3DTopoItemOwnersManager *
TopologyOwnersManagerCache::getOwnersManager(A3DRiRepresentationItem *brepOwner)
{
    // Check if it is in the cache
    for (int i=0; i < m_cacheSize; i++)
    {
        if (m_brepItems[i] == brepOwner)
        {
            return m_ownersManagers[i];
        }
    }

    // If the cache is full, remove the first entry and shift the rest down
    int cacheIndex = m_cacheEmptyIndex;
    if (cacheIndex < 0)
    {
        cout << "Shifting cache down!" << endl;
        cacheIndex = m_cacheSize - 1;

        // Release the map of the first entry
        cout << "About to release : " << m_ownersManagers[0] << endl;
        A3DTopoItemOwnersManagerGet((A3DRiRepresentationItem *)0, m_ownersManagers[0]);
        for (int i=1; i < m_cacheSize; i++)
        {
            m_ownersManagers[i-1] = m_ownersManagers[i];
            m_brepItems[i-1] = m_brepItems[i];
        }   
    }

    m_brepItems[cacheIndex] = brepOwner;

//crash is happening here on A3DTopoItemOwnersManagerGet() call
    if (A3DTopoItemOwnersManagerGet(brepOwner, m_ownersManagers[cacheIndex]) != A3D_SUCCESS) 
    {
        return  (A3DTopoItemOwnersManager *)0;
    }

    // Check if the cache is full now
    m_cacheEmptyIndex++;
    if (m_cacheEmptyIndex >= m_cacheSize)
    {
        m_cacheEmptyIndex = -1;
    }



    return m_ownersManagers[cacheIndex];

}
Yep
  • 141
  • 1
  • 13
  • Using `new` in C++ is really bad. It makes code look kinda like Java, but it's bad. Don't do it. Use `std::vector` instead. If you happen to be on some linux [Asan](https://clang.llvm.org/docs/AddressSanitizer.html) and [UBsan](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) can help you catch memory and undefined behavior issues. – nwp Nov 03 '17 at 15:22
  • 1
    A debugger will help you to find access violations. Be mindful of the last instruction executed before the access violation occurs. Put a breakpoint there and run again. This time look at the values of the variables. – Thomas Matthews Nov 03 '17 at 16:08
  • _"I have done some debugging"_ Where? I see no evidence that you tried to get a stack trace from the site of the crash, which is debugging 101. Also: `(A3DTopoItemOwnersManager *)0` is (A) why `nullptr` exists and (B) unnecessary if you were just to value-initialise during `new`; see https://stackoverflow.com/a/7546745/2757035 _Also_, as mentioned, you almost certainly should not be using `new` and `delete` in C++; its ethos discourages manual memory management, via a comprehensive Standard Library of containers that abstract that all away for you. – underscore_d Nov 03 '17 at 17:36

1 Answers1

0

Try set last variable of m_ownersManagers as 0 after shifting the cache down. Use in end of block

    if (cacheIndex < 0)
    {

after loop this line:

    m_ownersManagers[cacheIndex] = (A3DTopoItemOwnersManager *)0;
svm
  • 392
  • 3
  • 9