-4

Ich habe eine Klasse, die einen Zeiger std :: uint_8 enthält, und der Destruktor sollte aufgerufen werden, um den zugewiesenen Speicher zu löschen. Das Problem, das ich habe ist, dass ein Compiler-Fehler auftritt und besagt, dass der Speicher nicht zugewiesen wurde, aber ich weiß, dass ich es in meinem Standardkonstruktor zugewiesen. Hier ist mein Standard-Konstruktor:Destructor löscht zugewiesenen Speicher nicht

BigInteger::BigInteger() { 
    unsigned char aArray [4]; 
    aArray[0] = 0; 
    m_number = new unsigned char[4] 
    m_number = aArray; 
    m_digitCount = 0; 
    m_sizeReserved = 4; 
} 

und hier ist mein destructor:

BigInteger::~BigInteger() { 
    delete [] m_number; 
} 
+10

Was erwarten Sie 'm_number = aArray;' zu tun? – tkausl

+0

Sie ordnen 'm_number' mit' new' zu, aber in der nächsten Zeile weisen Sie es dem lokalen Array zu. –

+0

Was ist nicht nur ein Speicherverlust, sondern ist undefiniertes Verhalten, wenn Sie später 'm_number' verwenden – NathanOliver

Antwort

2

unsigned char aArray [4] hier erstellen Sie eine Reihe von 4 Elementen auf dem Stapel. Diese werden nach Beendigung des Konstruktors nicht mehr verfügbar sein.

m_number = new unsigned char[4] jetzt erstellen Sie 4 Elemente auf dem Heap. Sie ordnen den Speicher zu, und Sie werden für die Reinigung verantwortlich sein. Kein Problem, Sie tun dies im Destruktor.

m_number = aArray; Jetzt ändern Sie, was m_number zeigt auf, effektiv einen Zeiger auf den Speicher verloren, den Sie zugewiesen haben. Jetzt hast du ein Leck.

Jede Verwendung von m_number außerhalb dieses Konstruktor ist jetzt nicht definiertes Verhalten, weil Sie Sie kein Zugriff sind Speicher mehr besitzen.

delete [] m_number; jetzt sind löschen Sie Speicher Sie nicht besitzen. UB.

Sie neu zuweisen nicht m_number und Sie werden diese Probleme nicht haben. Besser noch, verwenden Sie std::vector und beobachten Sie, wie diese manuellen Speicherverwaltungsprobleme verschwinden.

0

Sie haben ein klassisches Szenario eines Speicher austreten. Im Wesentlichen, was Sie tun, ist die folgende:

  1. Weisen-Speicher (m_number = new unsigned char[4])
  2. Aufschalten der Zeiger, der auf diesem zugeordneten Speicherpunkte (m_number = aArray)
  3. nie den zugewiesenen Speicher, wie Sie löschen nicht mehr wissen, wo es ist - Sie haben den Zeiger auf sie verloren (es wurde überschrieben)
1

Diese Linie

m_number = aArray; 

weist die Adresse einer lokalen Variablen m_number zu.

Diese Adresse kann nicht in Verbindung mit delete [] m_number; verwendet werden, die mit new unsigned char[4] zugewiesene Speicheradresse wird überschrieben und geht nach dieser Zuweisung verloren.

Verwandte Themen