Ошибка выполнения строки при печати, даже если она отлично работает в функции - PullRequest
0 голосов
/ 22 марта 2012

работает над простой стековой программой на основе C ++. Я пытаюсь напечатать строку, которая является частью класса NameItem, который класс PointerStack использует в качестве своего типа элемента (см. Код). Всякий раз, когда я пытаюсь напечатать строку в функции main () моей программы, консоль печатает тарабарщину и повторяет звуковые сигналы. Однако, когда я вызываю функцию PrintPointerStack, ошибок нет, и все печатается, как и ожидалось.

Я пытался изменить классы, переставить код, и хотя я могу точно определить, какая строка вызывает ошибку, я не могу понять, почему. Я полностью потерян здесь, никогда не видел ничего подобного, поэтому извините, если ответ прост и найден в поиске в Google, но я искал несколько часов и просто не знаю, что искать.

Код ниже:

#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

#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;
    }
}

И класс NameItem

#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 << " ";
}

Последнее замечание: основная программа имеет больше кода для тестирования класса Stack, включенного в программу. Я удалил код, так как он не связан с ошибкой, и программа по-прежнему аварийно завершает работу, но происходит сбой сразу с окном ошибки Windows, а не с консольным бредом / гудками. Не уверен, что это актуально или нет ...

1 Ответ

2 голосов
/ 22 марта 2012

Проблема двоякая.

Сначала вы очищаете объект PStacker в PrintPointerStack(), а затем пытаетесь получить доступ к верхнему элементу этого пустого стека.Это должно бросить EmptyStack.Тот факт, что этого не происходит, также указывает на другую проблему (см. Ниже).

Во-вторых, тот факт, что гибериш печатается (иногда), указывает на то, что вы пытаетесь получить доступ к данным через недопустимые объекты / указатели.Действительно, поскольку вы передаете параметр PrintPointerStack() через передачу по значению, вызывается конструктор копирования по умолчанию, который слепо копирует значение указателя top.Затем вы продолжаете удалять объекты, но указатель top в исходном PStacker не изменяется, поэтому теперь недействителен.Отсюда ваша проблема.

Чтобы исправить, вам нужно либо передать параметр в PrintPointerStack() с помощью указателя / ссылки, либо предоставить более подходящий конструктор копирования, который выполняет глубокое копирование (вместо мелкой копии, предоставляемойконструктор копирования по умолчанию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...