2017-11-03 6 views
0

Mein Programm stürzt aufgrund einer Ausnahmezugriffsverletzung ab. Es passiert konsequent, also denke ich, es ist ein Code-Problem und kein Problem in der A3DTopoItemOwnersManagerGet() -Methode, aber ich bin mir nicht sicher. Ich habe etwas Debuggen gemacht und ich kann sagen, dass es konsequent passiert, nachdem der "Cache nach unten verschoben wurde", was mich denken lässt, dass der Prozess des Verschiebens des Caches in einem anderen Array oder etwas passieren sollte. Ich bin hauptsächlich ein Java-Entwickler und habe sehr wenig C++ - Erfahrung, sieht dieser Code OK? In Java sieht es so aus, als ob es für mich in Ordnung wäre. Denkst du, der Absturz ist ein Problem im ts3d-Hoops A3DTopoItemOwnersManagerGet-Aufruf oder im folgenden Code?Zugriffsverletzung in meinem Code oder in Hoops-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]; 

} 
+0

Mit 'new' in C++ ist wirklich schlecht. Es macht Code ähnlich wie Java, aber es ist schlecht. Tu es nicht. Verwenden Sie stattdessen 'std :: vector'. Wenn Sie zufällig auf Linux [Asan] (https://clang.llvm.org/docs/AddressSanitizer.html) und [UBsan] (https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) können hilft Ihnen, Speicher und undefinierte Verhaltensprobleme zu fangen. – nwp

+1

Ein Debugger hilft Ihnen, Zugriffsverletzungen zu finden. Beachten Sie den letzten Befehl, der ausgeführt wird, bevor die Zugriffsverletzung auftritt. Setzen Sie dort einen Haltepunkt und führen Sie ihn erneut aus. Schau dir diesmal die Werte der Variablen an. –

+0

_ "Ich habe ein Debugging durchgeführt" _ Wo? Ich sehe keinen Beweis, dass Sie versucht haben, eine Stack-Ablaufverfolgung von der Seite des Absturzes zu bekommen, die das Debugging 101 ist. Außerdem: '(A3DTopoItemOwnersManager *) 0' ist (A) warum' nullptr' existiert und (B) unnötig, wenn Sie es wären nur um während "new" zu initialisieren; siehe https://StackOverflow.com/a/7546745/2757035 _Also_, wie erwähnt, sollten Sie in C++ mit '' '' '' ''' '' '' '' '' 'nicht wirklich anfangen. Sein Ethos entmutigt das manuelle Speichermanagement über eine umfassende Standardbibliothek von Containern, die alles für Sie abstrahieren. –

Antwort

0

Versuchen gesetzt letzten Variable von m_ownersManagers als 0 nach unten um den Cache zu verschieben. Verwendung in Blockende

if (cacheIndex < 0) 
    { 

nach Schleife dieser Zeile:

m_ownersManagers[cacheIndex] = (A3DTopoItemOwnersManager *)0;