0

我写了一个 FIFO 队列,但我不断收到调试错误;MS VS2008 说:

调试器中的“此应用程序已请求运行时以不寻常的方式终止它”:fifoQueue.exe 中 0x7c81eb33 处的未处理异常:Microsoft C++ 异常:内存位置 0x0012f340 处的 std::bad_alloc ..

问题似乎来自程序的最后一部分,我试图打印存储到 FIFO 队列数组中的信息。它只打印第一项,然后崩溃。

#include <iostream>
#include <fstream>
#include <string>
#include "QueType.h"
#include <queue>

using namespace std;

struct movieType
{ 
string name;
char genre;
};

int main()
{
movieType movie[3];

movie[0].name="snatch"; movie[0].genre='A';
movie[1].name="layer cake "; movie[1].genre='A';
movie[2].name="rasing twins "; movie[2].genre='C';

queue<movieType> PQqueue;
for (int i=0;i<3;++i)
    PQqueue.push(movie[i]);

QueType<movieType> fifoQueue[3];

string Genre[3]={"Action", "Comedy", "Drama"};

movieType it;

while (!PQqueue.empty())
{
    it=PQqueue.front();
    PQqueue.pop();

    if (it.genre == 'A')
        fifoQueue[0].Enqueue(it);
    else if (it.genre == 'C' )
        fifoQueue[1].Enqueue(it);
    else if (it.genre == 'D')
        fifoQueue[2].Enqueue(it);
}

//!!! problem seems to come from here
movieType ij;
for (int i=0; i<3; ++i)
{
    while(!fifoQueue[i].IsEmpty())
    {
        fifoQueue[i].Dequeue(ij);
        cout<<ij.name<<endl;
    }
}

return 0;
}

以及 QueType.h 的实现文件

#include <cstddef> //for NULL
#include <new> // for bad_alloc
//definition of NodeType
template <class ItemType>
struct NodeType
{
ItemType info; // store data
NodeType* next; // sotre location of data
};

//exception class used when queue is full
class FullQueue
{};

//Exception class used when queue is empty
class EmptyQueue
{};

//templated queue class
template<class ItemType>
class QueType
{
public:
    QueType();
    //Function: class constructor
    //Precondition: none
    //Postcondition: it initializes the pointers, front and rear to null

    ~QueType();
    //Function:class destructor
    //Precondition: queue has been initialized
    //Postcondition: deallocate allocated memory

    void MakeEmpty();
    //Function: determines whether the queue is empty
    //Precondition: queue has been initialized
    //Postcondition:queue is empty

    bool IsEmpty() const;
    //Function:determines whether the queue is empty
    //Precondition:queue has been initialized
    //Postcondition:Function value = (queue is empty)

    bool IsFull() const;
    //Function:determines whether the queue is full
    //Precondition:queue has been initialized
    //Postcondition:Function value = (queue is full)

    void Enqueue(ItemType newItem);
    //Function:Adds newItem to the rear of the queue
    //Precondition:queue has been initialized
    //Postcondition:if (queue is full), FullQueue exception is thrown,
    //else newItem is at rear of queue

    void Dequeue(ItemType& item);
    //Function:removes front item from the queue and returns it in item
    //Precondition:queue has been initialized
    //Postcondition:if (queue is empty), EmptyQueue exception is thrown
    //and item is undefines, else front element has been removed from
    //queue and item is a copy of removed element

private:
    NodeType<ItemType>* front; //pointer points to the front to the queue
    NodeType<ItemType>* rear; // pointer points to the rear of the queue
};


template<class ItemType>
QueType<ItemType>::QueType()
{
front = NULL;
rear = NULL;
}

template <class ItemType>
QueType<ItemType>::~QueType()
{
MakeEmpty();
}

template <class ItemType>
void QueType<ItemType>::MakeEmpty()
{
NodeType<ItemType>* tempPtr;//temporary pointer

while(front != NULL)
{
    tempPtr=front;
    front = front->next;
    delete tempPtr;
}
rear = NULL;
} 

template <class ItemType>
bool QueType<ItemType>::IsEmpty() const
{
return (front == NULL);
}

template <class ItemType>
bool QueType<ItemType>::IsFull() const
{
NodeType<ItemType>* location;
try
{
    location = new NodeType<ItemType>;
    delete location;
    return false;
}
catch(std::bad_alloc exception)
{
    return true;
}
}

template <class ItemType>
void QueType<ItemType>::Enqueue(ItemType newItem)
{
if (IsFull())
        throw FullQueue();
else
{
    NodeType<ItemType>* newNode;
    newNode = new NodeType<ItemType>;
    newNode ->info=newItem;
    newNode->next=NULL;
    if(rear== NULL)
            front= newNode;
    else
            rear->next=newNode;
    rear=newNode;
}
}

template <class ItemType>
void QueType<ItemType>::Dequeue(ItemType &item)
{
if(IsEmpty())
    throw EmptyQueue();
else
{
    NodeType<ItemType>* tempPtr;
    tempPtr = front;
    item= front->info;
    if(front== NULL)
            rear=NULL;
    delete tempPtr;
}
}
4

2 回答 2

0

从你的Dequeue功能:

NodeType<ItemType>* tempPtr;
tempPtr = front;
item= front->info;
if(front== NULL)
        rear=NULL;
delete tempPtr;

实际上,您永远不会使任何东西出队,您只需释放前指针。因此,当您循环时,IsEmpty将返回false,因此您将Dequeue再次调用,并再次访问并释放您已经释放的指针。

于 2012-08-27T07:58:35.247 回答
0

在您的Dequeue函数中,您删除了 指向的对象front,但您从未设置frontNULL,因此您的IsEmpty()方法在不应该返回 false 时返回。

NodeType<ItemType>* tempPtr;
tempPtr = front;
item= front->info;
if(front== NULL)
        rear=NULL;
delete tempPtr; // deleted object pointed at by front, but front not set to NULL
于 2012-08-27T08:06:37.217 回答