2016-04-28 6 views
1

Ich habe seit Stunden versucht, das herauszufinden, und ich bin am Ende meines Wissens. Ich würde es sicherlich schätzen, wenn mir jemand sagen könnte, wenn ich falsch liege.Heap Corruption im Klassenzerstörer?

Ich schrieb einen C++ - Code mit Klasse, die einen einfachen Stapel implementiert und versucht, einen zufälligen Zeichenstrom zu pushen und zu popularisieren. Es scheint gut zu funktionieren, aber am Ende der Datei, erzeugt es eine Art von Laufzeitfehler:

HEAP CORRUPTION DETECTED: after Normal block....

Da der Fehler am Ende der Datei auftritt, ist meine Vermutung, dass es ein Problem beim Löschen des Zeigers (Klassendestruktor). Ich habe jedoch keine Ahnung, was mit dem Destruktor, den ich geschrieben habe, nicht stimmt.

Auch nach ein paar Versuchen und Fehler, fand ich heraus, dass, wenn ich eine größere Zahl auf vorzeichenlose Integer-Wert iter1 (ex: 80), der Laufzeitfehler nicht auftritt. Kannst du erklären, was das Problem ist und wie man es umgehen kann?

stack.h:

class sstack 
{ 
public: 
    sstack(int length = 256); 
    ~sstack(void); 
    int sstackPop(char &c); 
    int sstackPush(char c); 
    bool isempty(); 
    bool isFull(); 

protected: 
private: 
    char *sstackBuffer; 
    int sstackSize; 
    int sstackIndex; // Initial = -1 
}; 

stack.cpp:

#include "stack.h" 
#include <iostream> 
using namespace std; 

sstack::sstack(int length) 
{ 
    sstackIndex = -1; 
    if (length > 0) 
     sstackSize = length; 
    else 
     sstackSize = 256; 

    sstackBuffer = new char[sstackSize]; 
} 

sstack::~sstack(void) 
{ 
    delete[] sstackBuffer; 
} 

bool sstack::isempty() 
{ 
    if (sstackIndex < 0) 
    { 
     cout << "is empty!(isempty)" << endl; 
     return 1; 
    } 
    else 
     return 0; 
} 

bool sstack::isFull() 
{ 
    if (sstackIndex >= sstackSize) 
     return 1; 
    else 
     return 0; 
} 


int sstack::sstackPop(char &c) 
{ 
    if (!isempty()) 
    { 
     c = sstackBuffer[sstackIndex--]; 
     cout << sstackIndex << endl; 
     return 1; 
    } 
    else 
    { 
     cout << "is empty!(sstackPop)" << endl; 
     return 0; 
    }  
} 

int sstack::sstackPush(char c) 
{ 
    if (!isFull()) 
    { 
     sstackBuffer[++sstackIndex] = c; 
     return 1; 
    } 
    else{ 
     return 0; 
    } 

} 

main.cpp:

#include <iostream> 
#include "stack.h" 
#include <string> 
using namespace std; 

int main(){ 
    unsigned int iter1 = 5; 
    unsigned int iter2 = 800; 

    sstack stackDefault; 
    sstack stack1(iter1); 
    sstack stack2(iter2); 

    char buffer[80]; 
    memset(buffer, 0x00, 80); 
    char BUFFER[80] = "A random stream of characters"; 
    strcpy_s(buffer, 80, BUFFER); 

    for (int i = 0; i< strlen(buffer); i++) 
    { 
     cout << " stack1: " << stack1.sstackPush(buffer[i]); 
     cout << " stack2: " << stack2.sstackPush(buffer[i]); 
     cout << " stackD: " << stackDefault.sstackPush(buffer[i]); 
     cout << " i : "<< i << endl; 
    } 

    cout << "out of Pushes" << endl; 

    int i = 0; 
    memset(buffer, 0x00, 80); 
    while (!stack1.isempty()) 
     stack1.sstackPop(buffer[i++]); 

    cout << buffer << endl; 
    getchar(); 

} 

Antwort

3

sstackBuffer[++sstackIndex] = c;

Wird über das Ende des sstackBuffer schreiben, wenn der Stapel hat nur noch ein Element übrig.

Wenn Sie einen Stapel Größe betrachten 1. Im ersten Aufruf dieser Linie drücken, um würde bewerten:

sstackBuffer[1] = c;

, die über den Speicher ist Ihnen zugeordnet haben.

Stellen Sie sicher, dass Sie den Unterschied zwischen den Operatoren pre-increment and post-increment kennen. In Ihrem Codebeispiel würde ich vorschlagen, dass Sie post-increment in push und pre-increment in pop verwenden.

+0

Bestätigt, vielen Dank! –