allPlaylists is a vector of type Playlist.

listSongs is a vector of type *Songs.

//Loop that goes through each element in the playlist vector.
				for(int k = 0; k < allPlaylists.size(); k++)
				{		
                                        // loop that goes through each song within the Playlist vector element. listSongs is a vector of Song pointers.
					for (int g = 0; g < (allPlaylists.at(k).listSongs.size() - 1); g++)								
					{ 
                     // Checks if songDelete (input earlier) is an element in any of the playlists.
                     // If it is, checks if artistDelete is an element of that of the playlist for that song.
						if(songDelete == allPlaylists.at(k).listSongs.at(g)->getSongName())
							if(artistDelete == allPlaylists.at(k).listSongs.at(g).getArtistName())
							{
	// If the song and artist exist, I delete that song element from the vector listSongs, and output a message.							allPlaylists.at(k).listSongs.erase(allPlaylists.at(k).listSongs.begin() + g);
								cout << songDelete << "was deleted from your " << allPlaylists.at(k).getPlaylistName() << " playlist." << endl;
								continue;
							}
					}
                  // Then I delete the element from the entire music library. library is a vector of Song objects.
				cout << songDelete << " was deleted from the library." << endl; 
				break;
				}

No matter what I do, I get a Seg Fault. I think I need to erase the Playlist pointers to the songs before I can erase the song object in library, right?

Recommended Answers

All 8 Replies

I think the problem is how I access the second vector, but I don't know how to fix it.

cout << allPlaylists.at(0).getPlaylistName(); // Does work, but...

cout << allPlaylists.at(0).listSongs.at(0).getSongName(); // Causes a seg fault.

How would I access a function for a vector of a vector if not that way?

You say that listongs is a vector of song* so the proper way to access its members is with a ->
so something like: cout << allPlaylists.at(0).listSongs.at(0)->getSongName(); might work

I post on the others. They take a few hours to respond usually.

Song.H

#ifndef SONGS_H_
#define SONGS_H_

#include <string>
#include <vector>
using namespace std;

class Songs																				// Songs - Class of song information and functions.
{
	private:
		string songName;																// songName = Name of song.
		string artistName;																// artistName = Name of artist.
		string albumName;																// albumnName = Name of album.
		string genre;																	// genre = Genre of song (5 options).
        int playTime; 																	// playTime = Song length in positive seconds.
        int year;																		// year = Year song was made (positive integer; >= 1900).
		int starRating;																	// starRating = Song star rating given by user (1-5).
	public:
		Songs();																		// Default Constructor - Sets everything to "nothing".
		Songs(string SN, string ArN, string AlN, int PT, int YR, int SR, string GR);	// Constructor - Sets everything to user input.
		string getSongName();															// Getter - Gets song name.
		void setSongName(string newSong);												// Setter - Sets song name.
		string getArtistName();															// Getter - Gets artist name.
		void setArtistName(string newArtist);											// Setter - Sets artist name.
		string getAlbumName();															// Getter - Gets album name.
		void setAlbumName(string newAlbum);												// Setter - Sets album name.
		int getPlayTime();																// Getter - Gets play time.
		void setPlayTime(int newTime);													// Setter - Sets play time.
		int getYear();																	// Getter - Gets song year.
		void setYear(int newYear);														// Setter - Sets song year.
		int getStarRating();															// Getter - Gets star rating.
		void setStarRating(int newStarRating);											// Setter - Sets star rating.
		string getSongGenre();															// Getter - Gets song genre.
		void setSongGenre(string newGenre);												// Setter - Sets song genre.
		Songs addSongLibrary(vector<Songs> &library);			
		void printLibrary(vector<Songs> &library);
		void printReviewPlaylist(vector<Songs> &playlist);								// Playlist Function - Prints current playlist, and allows user to search for and delete current songs.
		void printBoth(vector<Songs> library, vector<Songs> playlist);					// Library/Playlist Function - Prints final library and final playlist.
};

#endif

Playlist.H

#ifndef PLAYLIST_H_
#define PLAYLIST_H_

#include "songs.h"
#include <string>
#include <vector>
using namespace std;

class Playlist	
{
	private:
		vector <Songs*> listSongs;
		string listName;
	public:
		Playlist();
		Playlist(string newName);
		void setPlaylistName(string playlistName);
		string getPlaylistName();
		void playlistAdd(vector<Playlist> &allPlaylists, Songs *newSong);
		bool searchAndAdd(vector<Playlist> &allPlaylists, Songs *newSong);
		void createAndAdd(vector<Playlist> &allPlaylists, Songs *newSong);
		void editLibrary(vector<Playlist> &allPlaylists, vector<Songs> &library);
};

#endif

Playlist.cpp (IT'S UNDER THE EDIT LIBRARY FUNCTION, AFTER IF('D))

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include "playlist.h"
using namespace std;

// Default Constructor.
Playlist::Playlist()
{
	listName = " ";
	listSongs.push_back(NULL);
}

// Constructor
Playlist::Playlist(string newName)
{
	listName = newName;
	listSongs.push_back(NULL);
}

void Playlist::setPlaylistName(string playlistName)
{
	listName = playlistName;
}

string Playlist::getPlaylistName()
{
	return listName;
}

void Playlist::playlistAdd(vector<Playlist> &allPlaylists, Songs *newSong)
{
	Playlist tempList;
	char addChoice, listChoice;
	bool flag;
	cout << endl << "Enter first character y to add song to playlist, or enter any other character to return to menu: ";	
	cin >> addChoice;														
	if(addChoice == 'y')	
	{
		while(true)
		{
			cout << endl << "---Playlist Options---" << endl;
			cout << "(1) Enter first character S to search for a current playlist to add to." << endl;
			cout << "(2) Enter first character N to create and add to a new playlist." << endl;
			cout << "(3) Enter first character X to return to menu without adding to a playlist." << endl;
			cout << " \t Enter: ";
			cin >> listChoice;
			if(listChoice == 'S')
			{
				flag = tempList.searchAndAdd(allPlaylists, newSong);
				if(flag)
					break;
				else
					continue;
			}
			else if(listChoice == 'N')
			{
				tempList.createAndAdd(allPlaylists, newSong);
				break;
			}			
			else if(listChoice == 'X')
			{
				cin.clear();
				cin.ignore(1000,'\n');
				break;
			}
			else																
			{
				cout << endl << "***Invalid character. Please choose one of the three playlist options.***" << endl;			
				cin.clear();																				
				cin.ignore(1000,'\n');
				continue;																					// Goes to top of loop, rechecks mainChoice1, and reenters loop if no 'X'.
			}		
		}
	}
}

bool Playlist::searchAndAdd(vector<Playlist> &allPlaylists, Songs *newSong)
{
	string searchName;
	if(allPlaylists.size() <= 0)
	{
		cout << endl << "No playlists currently exist. Please choose again." << endl;
		return false;
	}
	cout << endl << "You currently have the following playlists: ";
	for(int j = 0; j < allPlaylists.size(); j++)
		cout << allPlaylists.at(j).getPlaylistName() << " | ";
	cout << endl;
	cin.clear();
	cin.ignore(1000, '\n');
	cout << " \t Enter the exact name of the playlist you would like to add to: ";
	getline(cin, searchName);
	cout << endl;
	for(int i = 0; i < allPlaylists.size(); i++)
	{
		if(searchName == allPlaylists.at(i).getPlaylistName())
			{
				allPlaylists.at(i).listSongs.push_back(newSong);
				cout << endl << "***Song was added to your " << searchName << " playlist.***" << endl;
				return true;
			}
	}
	cout << endl << "***Playlist not found. Please choose again.***" << endl;
	return false;
}

void Playlist::createAndAdd(vector<Playlist> &allPlaylists, Songs *newSong)
{
	string newName;
	bool flag = true;
	cin.clear();
	cin.ignore(100,'\n');
	while(flag)
	{
		cout << "Enter the name of your new playlist: ";
		getline(cin, newName);
		for(int i = 0; i < allPlaylists.size(); i++)
		{
			if(newName == allPlaylists.at(i).getPlaylistName())
			{
				cout << endl << "You already have a playlist called " << newName << ". Try again..." << endl << endl;
				flag = false;
			}
		}
	if(flag)
		break;
	else
		flag = true;
		continue;
	}

	int j = allPlaylists.size();
	Playlist *newList = new Playlist();
	newList->setPlaylistName(newName);
	allPlaylists.push_back(*newList);
	allPlaylists.at(j).listSongs.push_back(newSong);
	cout << endl << "***Song was added to your " << newName << " playlist.***" << endl;
}

void Playlist::editLibrary(vector<Playlist> &allPlaylists, vector<Songs> &library)
{
	Playlist temp;
	bool songDeleted = false, songFind = false, songAdded = false, alreadyOn = false;
	char optionChoice;
	string songDelete, artistDelete, songAdd, artistAdd, searchPlaylist;
	while(true)																		// Enters and stays in loop while flag is true.
	{
		cout << endl << "Library Options:" << endl;
		cout << "(1) Enter first character D to search for and delete a song (from library and all playlists)." << endl;
		cout << "(2) Enter first character A to search for a library song and add it to a playlist." << endl;
		cout << "(3) Enter first character X to return to main menu." << endl;		
		cout << " \t Enter: ";
		cin >> optionChoice;														// deleteChoice - Users inputs d to delete a song, or anything else to return to menu.
		if(optionChoice == 'D')
		{	
			int j;
			cin.ignore(10,'\n');
			cout << "Please enter the exact song name you would like to delete: ";	
			getline(cin, songDelete);					
			cout << endl << allPlaylists[0][0];
			cout << endl << endl << endl << endl;
			cout << "Please enter the artist of that song: ";
			getline(cin, artistDelete);				
			for(j = 0; j < library.size(); j++)
				{
					if(songDelete == library.at(j).getSongName())
						if(artistDelete == library.at(j).getArtistName())
						{
							songDeleted = true;
							break;
						}
				}
			if(songDeleted)
			{ 
				/*for(int k = 0; k < allPlaylists.size(); k++)
				{		
					for (int g = 0; g < (allPlaylists.at(k).listSongs.size() - 1); g++)								
					{ 
					
						if(songDelete == allPlaylists.at(k).listSongs.at(g)->getSongName())
							if(artistDelete == allPlaylists.at(k).listSongs.at(g).getArtistName())
							{
								cout << "Her";
								allPlaylists.at(k).listSongs.erase(allPlaylists.at(k).listSongs.begin() + g);
								cout << songDelete << "was deleted from your " << allPlaylists.at(k).getPlaylistName() << " playlist." << endl;
								continue;
							}
					}
				library.erase(library.begin() + j);*/
				cout << songDelete << " was deleted from the library." << endl; 
				break;
				
			}
			if(!songDeleted)
			{
				cout << endl << "***Song not found. Try again.***" << endl;			
				continue;															// Continues back to top of loop for user to search again.
			}				
		}
		else if(optionChoice == 'A')
		{	
			cin.ignore(10,'\n');
			cout << "Please enter the exact song name you would like to add to a playlist: ";	
			getline(cin, songAdd);					
			cout << "Please enter the artist of that song: ";
			getline(cin, artistAdd);				
			int t, f;
			for(t = 0; t < library.size(); t++)
				{
					if(library.at(t).getSongName() == songDelete)
						if(library.at(t).getArtistName() == artistDelete)
						{
							songFind = true;
							break;
						}
				}
			if(songFind)
			{
				if(allPlaylists.size() <= 0)
				{
					cout << endl << "No playlists currently exist." << endl;
					temp.createAndAdd(allPlaylists, &library[t]);
				}				
				else if(allPlaylists.size() > 0)
				{
					while(true)
					{
						cout << endl << "You currently have the following playlists: ";
						for(int h = 0; h < allPlaylists.size(); h++)
							cout << allPlaylists.at(h).getPlaylistName() << " | ";						
						cout << endl;
						cin.clear();
						cin.ignore(1000, '\n');
						cout << " \t Enter the exact name of the playlist you would like to add to: ";
						getline(cin, searchPlaylist);
						cout << endl;
						for(f = 0; f < allPlaylists.size(); f++)
						{
							if(searchPlaylist == allPlaylists.at(f).getPlaylistName())
								{
									songAdded = true;
									continue;
								}
						}
						if(songAdded)
							break;
						else
							cout << endl << "***Playlist not found. Please choose again.***" << endl;	
							continue;
					}
					for (int e = 0; e < allPlaylists.at(f).listSongs.size(); e++)								
					{
						if(allPlaylists.at(f).listSongs.at(e)->getSongName() == songAdd)
							if(allPlaylists.at(f).listSongs.at(e)->getArtistName() == artistAdd)
							{
								cout << songAdd << "is already on your " << allPlaylists.at(f).getPlaylistName() << " playlist." << endl;
								alreadyOn = true;
							}
					}
					if(alreadyOn)
						break;
					else
						allPlaylists.at(f).listSongs.push_back(&library.at(t));
				}	
				break;
			}
			else if(!songFind)
				cout << endl << "***Song not found. Try again.***" << endl;			
			continue;	
		}
		else if(optionChoice == 'A')
		{	
			cout << endl;	
		}
		else																
		{
			cout << "Invalid character. Please choose one of the three playlist options." << endl;			
			cin.clear();																				
			cin.ignore(1000,'\n');
			continue;																					// Goes to top of loop, rechecks mainChoice1, and reenters loop if no 'X'.
		}				
	}
}

You say that listongs is a vector of song* so the proper way to access its members is with a ->
so something like: cout << allPlaylists.at(0).listSongs.at(0)->getSongName(); might work

No dice. I've tried all variations of that statements. I think I'm accessing the songs wrong. Do I need a return songName function in Playlist as well as Song.

Why are you doing a thing like listSongs.push_back(NULL); there? Are you sure that you are not doing e.g. a listSongs.at( [I]index of a NULL pointer[/I] )->getSongName() causing the seg fault?

It may make sense to make use of your debugger to try to find the problem here.

Try running a debug build from your IDE. When the seg-fault occurs you should be given the opportunity to break out of the program and you'll be shown the line of code that causes the seg fault.

If it's a line of your own code that's highlighted, then you should be able to trace the problem back fairly easily. If it highlights any other code (lower level system code or std library code, or STL code etc) then you just need to take a look up the call-stack until you see something that you recognise from your code. Clicking on that part of the call stack should bring up the line of your code that is causing the seg fault further down the stack.

Once you've located the offending line of code, you should find it easier to diagnose the problem.

If that still doesn't help, it may be worth setting some breakpoints in your code near to the point in your code where the segfault occurs.
That way you can break out and step through your code whilst keeping an eye on the values in any relevant variables.
Keep stepping through the code and watching the variables until the seg-fault occurs. As long as you're watching the right things, the cause of the seg-fault should become more or less apparent.

Cheers for now,
Jas.

I've used a debugger, and the seg faults occur whenever I use a statement with allPlaylists/listSongs.

For example, like this: allPlaylists.at(0).listSongs.at(0)->getSongName();

How can I use Songs getSongName function for listSongs (which is of type *Songs)?

Urgent bump is urgent. I have an hour right now to sort this out. Any help would be much appreciated.

commented: It's not urgent for us, and bumping is rude to everyone else who has a question. -4
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.