c ++ - Runtime fejludskrivningsstreng, selv om det virker fint i en funktion

Indlæg af Hanne Mølgaard Plasc

Problem



arbejder på et simpelt C ++-pointer-baseret stakprogram. Jeg forsøger at udskrive en streng, der er en del af NameItem-klassen, som PointerStack-klassen bruger som sin varetype (se kode). Når jeg forsøger at udskrive strengen i hovedprogrammet () i mit program, udskriver konsollen gibberish og bipper gentagne gange. Men når jeg kalder funktionen PrintPointerStack, er der ingen fejl, og alt udskriver som forventet.


Jeg har prøvet at ændre klasserne, omarrangere koden, og mens jeg kan bestemme hvilken linje der genererer fejlen, kan jeg ikke finde ud af hvorfor. Jeg er helt tabt her, aldrig set noget her før, så jeg beklager, hvis svaret er enkelt og fundet i en google-søgning, men jeg har gået i timevis og ved bare ikke, hvad jeg skal søge længere.


Koden er under:


#include <iostream>
#include <string>
#include <stack>
#include <cstddef>
#include <new>
using namespace std;

#include "NameItem.cpp"
#include "Stack.cpp"
#include "PointerStack.cpp"

void PrintPointerStack(PointerStack printer){
    NameItem temp;
    while(!printer.IsEmpty()){
        temp = printer.Top();
        printer.Pop();
        temp.Print();
    }
    cout << endl;
}

int main(){

    string initNames[] = {"Michael","Charlie","Susan","Alexa",
                          "Jason","Candice","Beatrice","Lois",
                          "Peter","Matthew"};
    int initNamesLen = 10;

    PointerStack PStacker, tempPStacker;

    NameItem filler;

    for(int i = 0; i < initNamesLen; i++){
        filler.Init(initNames[i]);
        PStacker.Push(filler);
    }
    cout << endl << "---------- Pointer-based Stack ----------" << endl << endl;

    PrintPointerStack(PStacker);

    cout << "Top: ";
    (PStacker.Top()).Print(); //This is where the program errors. I've tried creating a
                              //temp variable like in the function above, and I've
                              //tried accessing the string directly and printing it
                              //from main() using cout, which produce the same results.
                              //So the error is caused specifically by the cout <<
                              //string statement, when I try to use that statement
                              //within the bounds of the main function.  
    cout << endl;

    PrintPointerStack(PStacker);

    cout << endl << "Popped: ";
    (PStacker.Top()).Print();
    PStacker.Pop();
    (PStacker.Top()).Print();
    PStacker.Pop();
    cout << endl;

    PrintPointerStack(PStacker);

    cout << endl << "Pushed: Sammy Valerie" << endl;
    filler.Init("Sammy");
    PStacker.Push(filler);
    filler.Init("Valerie");
    PStacker.Push(filler);

    PrintPointerStack(PStacker);

    try{
        PStacker.Push(filler);
    }
    catch(FullStack){
        cout << endl << "Stack is full, name not pushed" << endl;
    }

    cout << endl << "Popped: ";
    while(!PStacker.IsEmpty()){
        filler = PStacker.Top();
        PStacker.Pop();
        filler.Print();
    }
    try{
        PStacker.Pop();
    }
    catch(EmptyStack){
        cout << endl << "Stack is empty, name not popped" << endl;
    }

    return 0;
}


PointerStack-klassen


#include "PointerStack.h"

PointerStack::PointerStack(){
    top = NULL;
}

/*PointerStack::~PointerStack(){
    Node* temp;

    while(top != NULL){
        temp = top;
        top = top->next;
        delete temp;
    }
}*/

void PointerStack::Push(NameItem item){
    if(IsFull())
        throw FullStack();
    else{
        Node* location;
        location = new Node;
        location->data = item;
        location->next = top;
        top = location;
    }
}

void PointerStack::Pop(){
    if(IsEmpty())
        throw EmptyStack();
    else{
        Node* temp;
        temp = top;
        top = top->next;
        delete temp;
    }
}

NameItem PointerStack::Top(){
    if(IsEmpty())
        throw EmptyStack();
    else{
        return top->data;
    }
}

bool PointerStack::IsEmpty() const{
    return (top == NULL);
}

bool PointerStack::IsFull() const{
    Node* location;
    try{
        location = new Node;
        delete location;
        return false;
    }
    catch(std::bad\_alloc& exception){
        return true;
    }
}


Og NameItem-klassen


#include <fstream>
#include "NameItem.h"

NameItem::NameItem()
{
    name = " ";
}
RelationType NameItem::ComparedTo(NameItem otherItem) const
{
    if (name < otherItem.name)
        return LESS;
    else if (name > otherItem.name)
        return GREATER;
    else 
        return EQUAL;
}
void NameItem::Init(string value)
{
    name = value;
}
void NameItem::Print() const
{
    cout << name << " ";
}


Endelig note, hovedprogrammet har mere kode til at teste Stack-klassen, der er inkluderet i programmet. Jeg fjernede koden, da den ikke er relateret til fejlen, og programmet kolliderer stadig, men det styrter øjeblikkeligt med en windows fejlfelt i stedet for med konsol gibberish/beeps. Ikke sikker på om det er relevant eller ej ...

Bedste reference


Problemet er to gange.


Først tømmer du PStacker objektet i PrintPointerStack() og forsøger derefter at få adgang til det øverste element i den tomme stack. Dette bør kaste en EmptyStack. At dette ikke sker, viser også et andet problem (se nedenfor).


For det andet angiver det faktum, at giberish udskrives (undertiden), at du forsøger at få adgang til data gennem ugyldige objekter/peger. Faktisk fordi du overfører parameteren til PrintPointerStack() via pass-by-værdi, kaldes standardkopi-konstruktoren, der blindt kopierer værdien af ​​top -pegeren. Så fortsætter du med at slette objekter, men top -pegeren i den oprindelige PStacker ændres ikke, og er nu ugyldig. Dermed dit problem.


For at rette, skal du enten overføre parameteren til PrintPointerStack() med peger/reference eller give en bedre tilpasningskopi-konstruktør, der gør en dyb kopi (i stedet for den lave kopi, der leveres af standardkopi-konstruktøren).