队列中的deque程序崩溃

时间:2014-05-31 15:36:40

标签: c++ crash queue

我的第一个问题在这里,所以请原谅我是否未能提供一些内容......

我正在做一个家庭作业项目,主要包括创建一个" Jukebox" (从txt文件导入/导出专辑,创建和播放"播放列表等)。

我被困在一点上: 当"玩"播放列表由一个自制的队列组成,其副本由歌曲出列并延时打印出来。这似乎在第一次运行程序时运行良好,但如果"播放"再次选择选项(使用相同的播放列表,从不同的菜单选项创建),它会在管理打印第一首歌曲之前崩溃。如果创建一个新的播放列表,它也会崩溃,但在崩溃之前它会设法打印一些歌曲(似乎取决于第一个/新播放列表中的歌曲数量......)。

通过打印输出,我已经能够跟踪崩溃到" item = n->数据"在deque函数中调用...但是不能理解为什么会崩溃。

以下是我认为应该相关的代码...如果我包含其他部分会有所帮助,请告诉我。

编辑:崩溃时显示的调试错误是:R6010已调用abort()

从播放列表中播放的方法:

void Jukebox::playList()
{
    if(songList.getNodes() > 0) 
    {
        Queue tmpList(songList);
        Song tmpSong;
        while(tmpList.deque(tmpSong)) {
            clock_t temp;
            temp = clock () + 2 * CLOCKS_PER_SEC ;
            while (clock() < temp) {}
        }
    }
    else
        cout << "There are no songs in the playlist!" << endl;
}

队列:

// Queue.h - Projekt-uppgift
//-----------------------------------------------------------------------------
#ifndef queue_h
#define queue_h
    #include "Song.h"
    using namespace std;
    typedef Song Item;
    class Node;
class Queue
{
    private:
        Node *first;
        Node *last;
        int nodes;

    public:
        Queue():first(nullptr),last(nullptr),nodes(0){};
        ~Queue();
        void enque(Item item);
        bool deque(Item &item);
        int getNodes() const { return nodes; }
        void empty();
};
#endif


// Queue.cpp - Projekt-uppgift
//-----------------------------------------------------------------------------
#include "queue.h"
using namespace std;

class Node
{
    public:
    Node *next;
    Item data;
    Node (Node *n, Item newData) : next(n), data(newData) {}
};

//------------------------------------------------------------------------------
// Funktionsdefinitioner för klassen Queue
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Destruktor
//------------------------------------------------------------------------------
Queue::~Queue()
{
    while(first!=0)
    {
        Node *tmp = first;
        first = first->next;
        delete tmp;
    }
}
//------------------------------------------------------------------------------
// Lägg till data sist i kön
//------------------------------------------------------------------------------
void Queue::enque(Item item)
{
    Node *pNew = new Node(0,item);
    if(getNodes() < 1)
        first = pNew;
    else
        last->next = pNew;
    last = pNew;
    nodes++;
}
//------------------------------------------------------------------------------
// Ta bort data först i kön
//------------------------------------------------------------------------------
bool Queue::deque(Item &item)
{
    if(getNodes() < 1)
        return false;
    //cout << "deque: test2" << endl;
    Node *n = first;
    //cout << "deque: test3" << endl;
    //cout << "item = " << item << endl;
    //cout << "first = " << first << endl;
    //cout << "n->data = " << n->data << endl;
    item = n->data;
    //cout << "deque: test4" << endl;
    first = first->next;
    //delete n;
    nodes--;
    if(getNodes() < 1)            // Kön BLEV tom
        last = nullptr;
    return true;
}
//------------------------------------------------------------------------------
// Töm kön
//------------------------------------------------------------------------------
void Queue::empty()
{
   while (getNodes() > 0)
   {
       Item item;
       deque(item);
   }
}
//------------------------------------------------------------------------------

曲:

// Song.h - Projekt-uppgift
//-----------------------------------------------------------------------------
#ifndef song_h
#define song_h
    #include "Time.h"
    #include <string>
    #include <iostream>
    using namespace std;
class Song
{
    private:
        string title;
        string artist;
        Time length;

    public:
        Song();
        Song(string pTitle, string pArtist, Time pLength);
        // Setfunktioner
        void setTitle(string pTitle);
        void setArtist(string pArtist);
        void setLength(Time pLength);
        // Getfunktioner
        string getTitle() const { return title;}
        string getArtist() const { return artist;}
        Time getLength() const { return length;}
};

ostream &operator<<(ostream &os, const Song &song);
istream &operator>>(istream &is, Song &song);

#endif


// Song.cpp - Projekt-uppgift
//-----------------------------------------------------------------------------
#include "Song.h"
#include "Constants.h"
#include <iostream>
//------------------------------------------------------------------------------
// Definiering av Songs medlemsfunktioner
//------------------------------------------------------------------------------
// Fövald konstruktor
//------------------------------------------------------------------------------
Song::Song()
{

}

//------------------------------------------------------------------------------
// Initieringskonstruktor
//------------------------------------------------------------------------------
Song::Song(string pTitle, string pArtist, Time pLength)
{
    title = pTitle;
    artist = pArtist;
    length = pLength;
}

//------------------------------------------------------------------------------
// Setfunktioner
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// setTitle
//   Ange titel
//------------------------------------------------------------------------------
void Song::setTitle(string pTitle)
{
    title = pTitle;
}
//------------------------------------------------------------------------------
// setArtist
//   Ange artist
//------------------------------------------------------------------------------
void Song::setArtist(string pArtist)
{
    artist = pArtist;
}
//------------------------------------------------------------------------------
// setTitle
//   Ange titel
//------------------------------------------------------------------------------
void Song::setLength(Time pLength)
{
    length = pLength;
}
//---------------------------------------------------------------------------
// Överlagring av utskriftsoperatorn
//---------------------------------------------------------------------------
ostream &operator<<(ostream &os, const Song &song)
{
    os << song.getTitle() << DELIM << song.getArtist() << DELIM << song.getLength();

    return os;
}
//---------------------------------------------------------------------------
// Överlagring av inmatningsoperatorn
//---------------------------------------------------------------------------
istream &operator>>(istream &is, Song &song)
{
    string tmpString;
    Time tmpLength;
    getline(is, tmpString, DELIM);
    song.setTitle(tmpString);
    getline(is, tmpString, DELIM);
    song.setArtist(tmpString);
    is >> tmpLength;
    is.get();
    song.setLength(tmpLength);
    return is;
}
//---------------------------------------------------------------------------

专辑:

// Album.h - Projekt-uppgift
//-----------------------------------------------------------------------------
#ifndef album_h
#define album_h
    #include "Song.h"
    #include <string>
    #include <vector>
    #include <iostream>
    using namespace std;
class Album
{
    private:
        string name;
        vector<Song> songs;

    public:
        Album();
        Album(string pNameTitle, vector<Song> pSongs);
        // Setfunktioner
        void setName(string pName);
        // Getfunktioner
        string getName() const { return name;}
        vector<Song> getSongs() const { return songs;}
        int getNumberOfSongs() const { return songs.size();}
        Time getTotalTime() const;
        void addSong(Song pSong);

        bool operator<(const Album &album) const;
};

ostream &operator<<(ostream &os, const Album &album);
istream &operator>>(istream &is, Album &album);

#endif

// Album.cpp - Projekt-uppgift
//-----------------------------------------------------------------------------
#include "Album.h"
#include "Constants.h"
#include <iostream>
#include <string>
//------------------------------------------------------------------------------
// Definiering av Albums medlemsfunktioner
//------------------------------------------------------------------------------
// Fövald konstruktor
//------------------------------------------------------------------------------
Album::Album()
{

}

//------------------------------------------------------------------------------
// Initieringskonstruktor
//------------------------------------------------------------------------------
Album::Album(string pName, vector<Song> pSongs)
{
    name = pName;
    songs = pSongs;
}

//------------------------------------------------------------------------------
// Setfunktioner
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// setName
//   Ange namn
//------------------------------------------------------------------------------
void Album::setName(string pName)
{
    name = pName;
}
//------------------------------------------------------------------------------
// addSong
//   Lägg till song
//------------------------------------------------------------------------------
void Album::addSong(Song pSong)
{
    songs.push_back(pSong);
}
//------------------------------------------------------------------------------
// getTotalTime
//   Returnera total speltid
//------------------------------------------------------------------------------
Time Album::getTotalTime() const
{
    Time tTime(0,0,0);
    for(Song s : songs)
    {
        tTime = tTime + s.getLength();
    }
    return tTime;
}
//---------------------------------------------------------------------------
// Mindre än
//---------------------------------------------------------------------------
bool Album::operator<(const Album &album) const
{
    return getTotalTime() < album.getTotalTime();
}
//---------------------------------------------------------------------------
// Överlagring av utskriftsoperatorn
//---------------------------------------------------------------------------
ostream &operator<<(ostream &os, const Album &album)
{
    os << album.getName() << endl;
    os << album.getNumberOfSongs() << endl;
    for (size_t i = 0; i < album.getSongs().size(); i++)
        os << album.getSongs().at(i) << endl;

    return os;
}
//---------------------------------------------------------------------------
// Överlagring av inmatningsoperatorn
//---------------------------------------------------------------------------
istream &operator>>(istream &is, Album &album)
{
    string tmpString;
    int tmpNumberOfSongs;
    Song tmpSong;
    getline(is, tmpString);
    album.setName(tmpString);
    is >> tmpNumberOfSongs;
    is.get();
    for (int i = 0; i < tmpNumberOfSongs; i++)
    {
        is >> tmpSong;
        album.addSong(tmpSong);
    }
    return is;
}
//---------------------------------------------------------------------------

时间:

// Time.h - Projekt-uppgift
//-----------------------------------------------------------------------------
#ifndef time_h
#define time_h
    #include <iostream>
    using namespace std;
class Time
{
    private:
        int hours;
        int minutes;
        int seconds;

    public:
        Time();
        Time(int pHour, int pMinute, int pSecond);
        // Setfunktioner
        void setHour(int pHour);
        void setMinute(int pMinute);
        void setSecond(int pSecond);
        // Getfunktioner
        int getHour() const { return hours;}
        int getMinute() const { return minutes;}
        int getSecond() const { return seconds;}

        Time operator+(const Time &time) const;
        bool operator==(const Time &time) const;
        bool operator<(const Time &time) const;
};

ostream &operator<<(ostream &os, const Time &time);
istream &operator>>(istream &is, Time &Time);

#endif


// Time.cpp - Projekt-uppgift
//-----------------------------------------------------------------------------
#include "Time.h"
#include <iostream>
//------------------------------------------------------------------------------
// Definiering av Times medlemsfunktioner
//------------------------------------------------------------------------------
// Fövald konstruktor
//------------------------------------------------------------------------------
Time::Time()
{

}

//------------------------------------------------------------------------------
// Initieringskonstruktor
//------------------------------------------------------------------------------
Time::Time(int pHour, int pMinute, int pSecond)
{
    setHour(pHour);
    setMinute(pMinute);
    setSecond(pSecond);
}

//------------------------------------------------------------------------------
// Setfunktioner
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// setHour
//   Ange timme
//------------------------------------------------------------------------------
void Time::setHour(int pHour)
{
    if(pHour>-1)
        hours = pHour;
    else
        hours = 0;
}
//------------------------------------------------------------------------------
// setMinute
//   Ange minut
//------------------------------------------------------------------------------
void Time::setMinute(int pMinute)
{
    if(pMinute < 60 && pMinute > -1) {
        minutes = pMinute;
    }
    else
        minutes = 0;
}
//------------------------------------------------------------------------------
// setSecond
//   Ange sekund
//------------------------------------------------------------------------------
void Time::setSecond(int pSecond)
{
    if(pSecond < 60 && pSecond > -1) {
        seconds = pSecond;
    }
    else
        seconds = 0;
}
//---------------------------------------------------------------------------
// Överlagring av utskriftsoperatorn
//---------------------------------------------------------------------------
ostream &operator<<(ostream &os, const Time &time)
{
    os << time.getHour()*3600+time.getMinute()*60+time.getSecond();
    return os;
}
//---------------------------------------------------------------------------
// Överlagring av inmatningsoperatorn
//---------------------------------------------------------------------------
istream &operator>>(istream &is, Time &time)
{
    int tmp;
    is >> tmp;
    time.setSecond(tmp%60);
    time.setMinute((tmp/60)%60);
    time.setHour(tmp/3600);
    return is;
}
//---------------------------------------------------------------------------
// Likhet
//--------------------------------------------------------------------------
bool Time::operator==(const Time &time) const
{
    return hours == time.getHour() && minutes == time.getMinute() && seconds == time.getSecond();
}
//---------------------------------------------------------------------------
// Mindre än
//---------------------------------------------------------------------------
bool Time::operator<(const Time &time) const
{
    if(hours == time.getHour()) {
        if(minutes == time.getMinute()) {
            return seconds < time.getSecond();
        }
        else {
            return minutes < time.getMinute();
        }
    }
    else {
        return hours < time.getHour();
    }
}
//---------------------------------------------------------------------------
// Addition
//---------------------------------------------------------------------------
Time Time::operator+(const Time &time) const
{
    return Time(hours+time.getHour() + (minutes+time.getMinute() + (seconds+time.getSecond())/60)/60, (minutes+time.getMinute() + (seconds+time.getSecond())/60)%60, (seconds+time.getSecond())%60);
}
//---------------------------------------------------------------------------

提前感谢您的帮助!

EDIT2:

没有想到包含更详细的崩溃信息(因为它没有在崩溃弹出窗口中显示,所以说)。无论如何,这是:

输出:

'Jukebox.exe' (Win32): Loaded 'C:\Users\User\Documents\Studier - IT\Objektbaserad programmering i C++\Inlämningsuppgifter\Projekt\Jukebox\Debug\Jukebox.exe'. Symbols loaded.
'Jukebox.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
'Jukebox.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
'Jukebox.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
'Jukebox.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp110d.dll'. Symbols loaded.
'Jukebox.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr110d.dll'. Symbols loaded.
The thread 0xe50 has exited with code 0 (0x0).
Unhandled exception at 0x0083630C in Jukebox.exe: 0xC0000005: Access violation reading location 0x0000003C.

调用堆栈:

>   Jukebox.exe!Song::getLength() Line 27   C++
    Jukebox.exe!operator<<(std::basic_ostream<char,std::char_traits<char> > & os, const Song & song) Line 59    C++
    Jukebox.exe!Queue::deque(Song & item) Line 55   C++
    Jukebox.exe!Jukebox::playList() Line 493    C++
    Jukebox.exe!Jukebox::play() Line 385    C++
    Jukebox.exe!Jukebox::run() Line 536 C++
    Jukebox.exe!main() Line 547 C++
    Jukebox.exe!__tmainCRTStartup() Line 536    C
    Jukebox.exe!mainCRTStartup() Line 377   C
    kernel32.dll!754d86e3() Unknown
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!7748bf39()    Unknown
    ntdll.dll!7748bf0c()    Unknown

1 个答案:

答案 0 :(得分:0)

我认为问题可能是dequeue释放了实际的项目,因为tmpList正在制作一个浅层的Songlist副本。

class Queue
{
    private:
        Node *first;
        Node *last;
        int nodes;

这意味着出列的delete n;是错误的。临时只是一个对象,它复制了int节点,以及第一个和最后一个指针。销毁指向的数据是每个节点仍然保留在主歌曲列表中使用的错误。这与你描述的症状一致,它首次运行,然后在播放列表完成后立即崩溃。

如果你可以减少歌曲列表,可以通过调用它来出列,然后按原样出列,需要一个标志来使delete n;有条件。您编写的Queue上有一个析构函数,如果它超出范围,则会删除队列,或传递给删除操作符。幸运的是,当tmp列表超出范围时列表为空,因此它不会损坏歌曲列表。

我确定问题已经明确,以说明一些常见问题。排队存储项目&amp;将其添加到列表中,而不是分隔存储&amp;排队概念,导致混乱。

正确的修复,取决于你是否有理由怀疑你是否已经通过构造函数对Queue对象进行了深层复制,尽管效率较低,Songlist受到出列的项目的影响,或者如果Songlist被销毁一气呵成。

相关问题