簡體   English   中英

運行時錯誤打印字符串,即使它在函數中工作正常

[英]Runtime error printing string, even though it works fine in a function

處理一個簡單的基於C ++指針的堆棧程序。 我試圖打印一個字符串,它是NameItem類的一部分,PointerStack類將其用作項類型(請參閱代碼)。 每當我嘗試在程序的main()函數中打印字符串時,控制台會反復打印亂碼和嘟嘟聲。 但是,當我調用PrintPointerStack函數時,沒有錯誤,所有內容都按預期打印。

我試過更改類,重新排列代碼,雖然我可以確定哪一行生成錯誤,但我無法弄清楚原因。 我完全迷失在這里,之前從未見過這樣的事情,所以我很抱歉,如果答案很簡單並且在谷歌搜索中找到,但我已經去了幾個小時,只是不知道該搜索什么。

代碼如下:

#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錯誤框,而不是控制台亂碼/嘟嘟聲。 不確定這是否相關......

問題是雙重的。

首先,您在PrintPointerStack()中清空PStacker對象,然后嘗試訪問該空堆棧的頂部元素。 這應該拋出一個EmptyStack 沒有發生這一事實也表明了另一個問題(見下文)。

其次,打印giberish(有時)的事實表明您試圖通過無效的對象/指針訪問數據。 實際上,因為您通過pass-by-value傳遞PrintPointerStack()的參數, PrintPointerStack()調用默認的復制構造函數來盲目復制top指針的值。 然后繼續刪除對象,但原始PStackertop指針不會更改,因此現在無效。 因此你的問題。

要修復,您需要通過指針/引用將參數傳遞給PrintPointerStack() ,或者提供一個更好的適合復制構造函數來執行深層復制(而不是默認復制構造函數提供的淺復制)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM