c++ - 运行时错误打印字符串,即使它在函数中工作正常

标签 c++ windows

正在研究一个简单的基于 C++ 指针的堆栈程序。我正在尝试打印一个字符串,它是 PointerStack 类用作其项目类型的 NameItem 类的一部分(请参阅代码)。每当我尝试在程序的 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;
}

指针堆栈类

#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。这没有发生的事实也表明存在另一个问题(见下文)。

其次,(有时)打印出乱码的事实表明您正在尝试通过无效的对象/指针访问数据。实际上,因为您是通过按值传递传递 PrintPointerStack() 的参数,所以会调用默认复制构造函数,盲目地复制 top 指针的值。然后你继续删除对象,但是原来的PStacker中的top指针没有改变,所以现在是无效的。因此你的问题。

要解决此问题,您需要通过指针/引用将参数传递给 PrintPointerStack(),或者提供一个更适合的复制构造函数来执行深复制(而不是默认复制构造函数)。

关于c++ - 运行时错误打印字符串,即使它在函数中工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9813023/

相关文章:

c++ - boost::spirit::qi 性能

java - 在 SWT 中获取 Active Shell,即使 Shell 不在焦点上

php - mysql不能添加2个外键

c++ - 显示 QT 上下文菜单时没有 keyReleaseEvent

c++ - AdjustTokenPrivileges 错误 6 - 句柄无效

windows - PowerShell - Invoke-Sqlcmd 结果到 Export-Csv 设置批处理行限制

当我将脚本作为 Windows 服务运行时,Python 代码无法按预期工作

c++ - 在 C++ 中转换类型时出错

java - 访问派生类对象的字段,C++ vs Java

c++ - 为什么运算符重载实现中的两个静态对象在 C++ 中总是相等的?