2012-03-21 2 views
0

함수에서 제대로 작동하더라도 런타임 오류 문자열을 출력합니다. PointerStack 클래스가 항목 유형 (코드 참조)으로 사용하는 NameItem 클래스의 일부인 문자열을 인쇄하려고합니다. 내 프로그램의 main() 함수에서 문자열을 인쇄하려고 할 때마다 콘솔이 횡설수설하고 경고음을 반복해서 출력합니다. 그러나 PrintPointerStack 함수를 호출하면 오류가없고 모든 것이 예상대로 인쇄됩니다. 나는 이유를 알아낼 수 없습니다 오류를 생성하는 라인을 정확히 파악할 수있는 반면간단한 C++ 포인터 기반 스택 프로그램에서 작동하는

나는 코드를 재 배열, 클래스를 변경 시도하고 싶습니다. 나는 완전히 여기에서 잃어 버렸습니다. 전에는 이런 일이 전혀 없었습니다. 그래서 대답이 간단하고 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 << " "; 
} 

최종 메모, 주요 프로그램은 스택 클래스를 테스트하기 위해 더 많은 코드를 가지고 프로그램에 포함되어 있습니다. 그것이 오류와 관련이 없기 때문에 나는 코드를 제거했고, 프로그램은 여전히 ​​충돌하지만, 콘솔 횡설수설/삐 소리보다는 오히려 창 오류 상자로 즉시 충돌합니다. 관련성이 있는지 여부는 확실하지 않습니다 ...

+0

'사용법 #include "NameItem.cpp"'- 당신이 선언 (인터페이스)가 아닌 .CPP 파일 (구현)와 헤더를 포함해야한다. –

+0

사실, 유용했을 지 모르지만 OP가 제공 한 코드에서 헤더를 재구성하는 것은 상대적으로 쉽습니다. – Attila

답변

2

문제가 두 가지입니다.

먼저 개체를 PrintPointerStack()에 비우고 그 빈 스택의 최상위 요소에 액세스하려고합니다. 이 값은 EmptyStack입니다. 이것이 일어나지 않는다는 사실은 또 다른 문제점을 나타냅니다 (아래 참조).

둘째, giberish 인쇄된다는 사실은 (가끔)는 유효하지 않은 오브젝트/포인터를 통해 데이터 액세스를 시도하고 있음을 나타냅니다. 실제로 PrintPointerStack() 매개 변수를 전달할 때 값을 통해 전달하기 때문에 기본 복사 생성자가 호출되어 top 포인터의 값을 맹목적으로 복사합니다. 그런 다음 개체를 삭제하지만 원래 PStacker에있는 top 포인터는 변경되지 않으므로 현재 유효하지 않습니다. 그러므로 당신 문제.

수정하려면 포인터/참조를 사용하여 PrintPointerStack()에 매개 변수를 전달하거나 기본 복사 생성자가 제공하는 얕은 복사본 대신 딥 복사본을 사용하는 더 적합한 적합한 복사본 생성자를 제공해야합니다.

+0

아, 아직 복사 생성자에 대한 경험이 없지만 전화가 끊어졌습니다. 하나를 구현하고 내 문제를 해결, 옳은 방향으로 나를 가리켜 주셔서 감사합니다. – pzuraq

관련 문제