struct object array, prog crashing

Learning struct and objects now. Why is my program crashing when I hit enter key after typing in artist name?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct songs {
string artist;
string track;
};

int main()
{
	char repeat = 'y';
	int i = 0;
	songs* favorite = new songs[i];

	while (repeat == 'y')
	{
		cout << "Song Tracker" << endl << endl;
		cout << "What is your favorite song" << endl;
		cout << "-----------------------------" << endl;
		cout << "Enter the artist name: ";
		getline(cin, favorite[i].artist);
		cout << endl << "Enter your favorite track from " << favorite[i].artist << ": ";
		getline(cin, favorite[i].track);
		cout << endl << endl << "Would you like to enter some more songs? (y or n): ";
		cin >> repeat;
		i++;
	}
return 0;
}
You've set up an array size of 0! Witch I'm sure is illegal?

int i = 0;

Then you:
songs* favorite = new songs[i];

Also, memory leak! Anything newed, should also be deleted!

1
2
new favorite[ i ];
delete[] favorite;

1
2
new favorite;
delete favorite;
Ok I see how that could be. I cannot run the program without initializing 'i' first though. How do I go about tackling the problem in the above code, correctly?
A quick simple fix:

1
2
3
4
5
6
7
8
int totalSongs = 5;
int i = 0;

songs * favorite = new songs[ totalSongs ];

// code

delete[] favorite;


Although. When using new, you can create an array without the need for a const int.

So you could infact ask the user for input, on how many they wish to enter.
could I take that same methodology and produce the array count identifier (not sure of the terminology) via the times the user has entered 'y' or (yes)? I want the array to be dynamic in terms of however many times the user decides to hit 'y' and continue, it will allow for it and make the appropriate accommodations in the array
Last edited on
No. Once an array has been created there is no way( I think I read a way, but it's way beyond my head and too difficult, lol ) to resize it.

Maybe use a vector? Then, if a user enters 'y', you push_back( songs() ); Then edit it once it's in the vector.

Other than that, you could get user input. Lets say;
Enter the total of records you wish to enter: 3
Save user input in totalSongs
Create the array with this
Loop until i is equal to totalSongs
Last edited on
Thanks Lynx!
No worries. (:
I completely worked around the struct subconsciously. This was suppose to be a practice in structs and objects ;(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
struct songs {
string artist;
string track;
};

int main()
{
	char repeat = 'y';
	int count = 0;
	songs favorite;
	string temp=" ";
	vector<string> tempartist;
	vector<string> temptrack;

	cout << "Song Tracker" << endl << endl;
	while (repeat == 'y')
	{
		cout << "What is your favorite song" << endl;
		cout << "-----------------------------" << endl;
		cout << "Enter the artist name: ";
		getline(cin, temp);
		tempartist.push_back(temp);
		cout << endl << "Enter your favorite track from " << tempartist[count] << ": ";
		getline(cin, temp);
		temptrack.push_back(temp);
		cout << endl << endl << "Would you like to enter some more songs? (y or n): ";
		cin >> repeat;
		count++;
		cin.ignore();
	}

	for (int i=0; i<count; i++){
		cout << "Favorite artist #" << i << " is: " << tempartist[i] << endl;
		cout << "Favorite track from " << tempartist[i] << " is: " << temptrack[i] << endl;
	}


return 0;
}


argh. I guess struct wouldn't be something to use in this application.
Last edited on
You've set up the vector wrong. It should be a vector of struct, songs!

vector< songs > mySongList;

Then, before you can edit the objects you create, you must first push_back() an empty struct of songs.

mySongList.push_back( songs() );

Then edit:
getline( cin, mySongList[ count ].artist );
I might as well ask now.

What are the primary applications to use the following for:

1.) Classes
2.) Structures
3.) Enum
4.) Typedef

??
Outstanding Lynx, Thanks sir.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;

struct songs {
string artist;
string track;
};

int main()
{
	char repeat = 'y';
	int count = 0;
	vector<songs> mySongList;
	mySongList.push_back( songs() );

	cout << "Song Tracker" << endl << endl;
	while (repeat == 'y')
	{
		mySongList.push_back( songs() );
		cout << "What is your favorite song" << endl;
		cout << "-----------------------------" << endl;
		cout << "Enter the artist name: ";
		getline(cin, mySongList[count].artist);
		cout << endl << "Enter your favorite track from " << mySongList[count].artist << ": ";
		getline(cin, mySongList[count].track);
		cout << endl << endl << "Would you like to enter some more songs? (y or n): ";
		cin >> repeat;
		count++;
		cin.ignore();
	}

	for (int i=0; i<count; i++){
		cout << "Favorite artist #" << i << " is: " << mySongList[i].artist << endl;
		cout << "Favorite track from " << mySongList[i].artist << " is: " << mySongList[i].track << endl;
	}


return 0;
}
Last edited on
I'll give you what I think/know. I'm not amazing at C++. lol.

Classes. Good for recreating 'objects', encapsulating the same code. i.e. If you had a lot of players in the same game of what ever, you don't want to have to code the same 'human' over and over. You just create an object of that class.

Structures. I kind of see these the same as classes. Just... less involved.

Enum. I use these quite a bit. Say, if you have a facing direction, up, left, down and right. You could create these as enum's. Then when you pass these to a function, instead of having a switch statement with 0, 1, 2 and 3, you can use explicit naming. Saves looking through code etc to find out what '3' is...

Typedef. So you want an iterator for a vector. You'd type something like:
std::vector< songs >::iterator it;
Every time you want a new iterator, for a different loop.

By typeing:
typedef std::vector< songs>::iterator songsIt;

When you need a new iterator, all you now need to type is:
songsIt;
Because you typedef'ed it as songsIT, songsIt is essentially typing the whole thing out.
Lines 17 & 22. You push_back() twice! You'll edit the first one, on first run of the loop. With index 2 empty. Then on second run, you'll edit index 2, when, again, you've just push_back()'ed another one!

push_back() once, just before the editing. Or you'll have empty struct's in the vector.

On a side note. My above post! I think that's my biggest 'word'(not code) reply ever! LOL

Edit:
Also, if anyone disagrees with anything in my above post. I'd like to know! I'm here to learn too! (:
Last edited on
Again, great information.

Let me tell you how I see it from what you said:

Classes - Used for grouping concepts of code into a reusable block, which you can create multiple instances of as objects.

Structures - Less involved..

Enum - Creates aliases that make code easier to read

Typedef - Allows you to define your own iterators and things of that nature? So the predefined reverse_iterator (in conjuction with rend and rbegin) must be a form of a typedef, correct?
Last edited on
Well, you worded it better... lol!

And typedef. You typedef any( as far as I know ) 'type':
1
2
3
4
5
6
7
8
9
typedef int blah;

int main()
{
	blah myInt = 7;
	cout << myInt << '\n';

	return 0;
}
7
Learned some good stuff tonight, tnkx lynx
Last edited on
No problem! Happy coding. (:
Topic archived. No new replies allowed.