My first question asked here, so please excuse if I fail to include something...
I'm working on a homework project, which basically consists of creating a "Jukebox" (importing/exporting albums from txt files, creating and "playing" a playlist, etc.).
I've become stuck on one point:
When "playing" the playlist, which consists of a self-made Queue, a copy of it is made from which songs are dequeued and printed out with a time delay. This appears to run fine on the first run through the program, but if the "play" option is chosen again (with the same playlist, created from a different menu option), it crashes before managing to print the first song. It also crashes if creating a new playlist, but then it manages to print some songs (seem to depend on the number of songs in the first/new playlists...) before crashing.
With printouts I've been able to track the crashing down to being on the "item = n-data" call in the deque function... but can't get my head around why this would crash.
Below is the code I think should be relevant... let me know if there are other parts that would help if I include.
Edit: The Debug Error shown on crash is: R6010 abort() has been called
The method to play from the playlist:
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:
// Queue.h - Projekt-uppgift
// Håkan Sjölin 2014-05-31
//-----------------------------------------------------------------------------
#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
// Håkan Sjölin 2014-05-31
//-----------------------------------------------------------------------------
#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:
// Song.h - Projekt-uppgift
// Håkan Sjölin 2014-05-15
//-----------------------------------------------------------------------------
#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
// Håkan Sjölin 2014-05-15
//-----------------------------------------------------------------------------
#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:
// Album.h - Projekt-uppgift
// Håkan Sjölin 2014-05-17
//-----------------------------------------------------------------------------
#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
// Håkan Sjölin 2014-05-17
//-----------------------------------------------------------------------------
#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:
// Time.h - Projekt-uppgift
// Håkan Sjölin 2014-05-15
//-----------------------------------------------------------------------------
#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
// Håkan Sjölin 2014-05-15
//-----------------------------------------------------------------------------
#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);
}
//---------------------------------------------------------------------------
Thanks in advance for any help!
Edit2:
Didn't think of including the more detailed crash info (as it didn't show in the crash pop-up, so to say). Anyway, here it is:
Output:
'Jukebox.exe' (Win32): Loaded 'C:\Users\Håkan\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.
Call stack:
> 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