C++ 来自队列的deque上的程序崩溃

C++ 来自队列的deque上的程序崩溃,c++,crash,queue,C++,Crash,Queue,我在这里问的第一个问题,所以如果我没有包括一些东西,请原谅 我正在做一个家庭作业项目,主要包括创建一个“自动存储塔”(从txt文件导入/导出相册,创建和“播放”播放列表,等等) 我被一点困住了: “播放”由自制队列组成的播放列表时,会制作一份副本,从中取出歌曲,并延迟打印出来。在第一次运行程序时,这似乎运行正常,但如果再次选择“播放”选项(使用从不同菜单选项创建的同一播放列表),它将在打印第一首歌曲之前崩溃。如果创建一个新的播放列表,它也会崩溃,但是它会在崩溃之前打印一些歌曲(似乎取决于第一个/

我在这里问的第一个问题,所以如果我没有包括一些东西,请原谅

我正在做一个家庭作业项目,主要包括创建一个“自动存储塔”(从txt文件导入/导出相册,创建和“播放”播放列表,等等)

我被一点困住了: “播放”由自制队列组成的播放列表时,会制作一份副本,从中取出歌曲,并延迟打印出来。在第一次运行程序时,这似乎运行正常,但如果再次选择“播放”选项(使用从不同菜单选项创建的同一播放列表),它将在打印第一首歌曲之前崩溃。如果创建一个新的播放列表,它也会崩溃,但是它会在崩溃之前打印一些歌曲(似乎取决于第一个/新播放列表中的歌曲数量…)

通过打印输出,我已经能够跟踪崩溃到deque函数中的“item=n->data”调用。。。但我无法理解为什么会崩溃

下面是我认为应该相关的代码。。。让我知道如果我包括其他部分,是否还有其他帮助

编辑:崩溃时显示的调试错误是: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;
}
调用堆栈:

>   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
Jukebox.exe!Ge::GETLIGHT()27行C++
Jukebox.exe!操作符我认为问题可能在于,出列是释放实际项目,因为tmpList正在制作歌曲列表的浅拷贝

class Queue
{
    private:
        Node *first;
        Node *last;
        int nodes;
这意味着
删除n是一个错误。临时对象只是一个对象,它复制了int节点以及第一个和最后一个指针。销毁指向的数据是错误的,因为每个节点仍保留在主歌曲列表中以供使用。这与您描述的症状是一致的,在播放列表中,它第一次起作用,然后在您完成任何操作后立即崩溃

如果你可以通过调用dequeue来减少歌曲列表,那么dequeue需要一个标志来使
删除n条件。在您编写的队列上有一个析构函数,它在队列超出范围时会将其分解,或者传递给delete操作符。幸运的是,当tmp列表超出范围时,该列表为空,因此不会损坏歌曲列表

class Queue
{
    private:
        Node *first;
        Node *last;
        int nodes;
我确信这个问题是为了演示一些常见的问题而指定的。将项目存储和添加到列表中,而不是将存储和排队概念分开,这会导致混淆


正确的修复方法取决于您是否有理由怀疑构造器应该创建队列对象的深度副本,尽管它效率较低,歌曲列表中的项目会退出队列,或者如果歌曲列表一次性被销毁。

它崩溃了。。。对于诊断您的问题来说,这些信息不是很有用。您是否已经调试了代码以缩小这些崩溃可能发生的位置和最终原因?@Hi@πάνταῥεῖ, 谢谢你看一看。我在崩溃时给出的错误中进行了编辑(调用了R6010 abort()。调试我已经缩小到崩溃似乎发生在“item=n->data”调用上(如文中所述)。Cheers'R6010 abort()'附带附加信息。澄清!谢谢@πάνταῥεῖ, 我现在已经做到了!0x3C是60位小数,很可能是您无意中重用了被覆盖的内存,因此无法访问*歌曲。您是否尝试对删除进行注释,并检查是否没有指针悬垂到帧中分配的内容(作为自动操作)?如果我理解正确,一个修复方法是为执行深度复制的队列添加构造函数。我试过了,但程序仍然以同样的方式崩溃。我编写的复制构造函数看起来是这样的(我做对了吗?第一次真的尝试深度复制。):
Queue::Queue(const Queue&q){First=new Node(*q.First);last=new Node(*q.last);nodes=q.getNodes();}
老实说,我认为删除
delete n修复程序。除非你在课堂上有关于复制整个结构的内容,否则我不应该担心深度复制。dequeue中的delete是“太敏感了”,当队列结束时,你有一个队列析构函数。好的,谢谢,伙计,到时候我们会用它的。干杯不过,当您听到“资源获取是初始化”时,您会记得这一点,即需要新建和删除对或打开/关闭文件,这往往容易出错&在异常时有泄漏或在出错时提前终止函数。祝你的课程好运!
// 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);
}
//---------------------------------------------------------------------------
'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
class Queue
{
    private:
        Node *first;
        Node *last;
        int nodes;