Arrays and Classes

So i'm fooling around with classes, fstream, and arrays. I'm (strangely) used to Javascript, where an Array is a pre-determined datatype, and all you would have to write would be var array1 = new Array(); or var array2 = [1,"2"];. I can see how this is similar to C++, where arrays are defined by what they contain:
std::string* entry_list [20] = {"1","2",etc...};
However, i'm a bit confused on writing data to an array. I've got four files, for experimentation, on creating a class, getting some stuff from a file, then writing it in an array so that the user can access it when they want.
SSCCE:
I've trimmed parts of the code that are unrelated.
My problem is that when I call database::add_entry, the program breaks on line 17 of database.cpp. Visual Studio gives me the error,
Unhandled exception at 0x00e71f07 in g_cpp_database.exe: 0xC0000005: Access violation writing location 0x33732a98.

How do I add information to my array?
Database.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
const int maxEntries = 20;
class database {
	public:
		int entry_list_length;
		database(void);
		~database(void);
		void addEntry();
		void add_entry(std::string title,std::string artist,std::string album,std::string length);
		void remove_entry(int entry_id);
		void display();
		void command(int option);
		void check_file();
		int exit();
	private:
		std::string* entry_list [maxEntries];
		int entry_list_current;
};

Database.cpp:
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
43
44
45
46
47
48
49
50
51
52
#include "database.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
database::database(void) {}
database::~database(void) {}
void database::add_entry(std::string title,std::string artist, std::string album,std::string length) {
	if (database::entry_list_length >= maxEntries) {
		return;
	} else {
		std::string tempArray [4] = {title,artist,album,length};
		if (database::entry_list_length == NULL || database::entry_list_current == NULL) {
			database::entry_list_length = 0;
			database::entry_list_current = 0;
		}
		database::entry_list[database::entry_list_current] = tempArray;
		for (int n=0;n<4;n++) {
			std::cout << tempArray[n] << std::endl;
		}
		database::entry_list_length++;
		database::entry_list_current++;
	}
}
void database::check_file() {
	using namespace std;
	ifstream musicFile;
	string line;
	musicFile.open("music.txt",ios::in);
	if (musicFile.is_open()) {
		getline(musicFile,line);
		if (line == "good") {
			bool remaining = true;
			while (remaining) {
				string title;
				string artist;
				string album;
				string length;
				getline(musicFile,title);
				getline(musicFile,artist);
				getline(musicFile,album);
				getline(musicFile,length);
				if (length == " " || length == "") {
					remaining = false;
				} else {
					database::add_entry(title,artist,album,length);
				}
			}
		}
	}
	musicFile.close();
}

main.cpp:
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
#include <iostream>
#include <string>
#include "database.h"
int main() {
	using namespace std;
	database dB;
	int option;
	bool mainMenu = true;
	bool running = true;
	dB.check_file();
	/*while (running) {
		while (mainMenu) {
			cout << "Welcome to the music catalog." << endl << "1)Enter new song" << endl << "2) display all songs" << endl << "10) exit";
			if (!(cin>>option)) {
				cout << "Please enter a numeric option." << endl;
				return 0;
			} else if (option == 10) {
				return 0;
			} else {
				mainMenu = false;
				dB.command(option);
			}
		}
	}*/
	system("PAUSE");
	return 0;
}

(I understand that using system("PAUSE"); is a bad idea, but this is just a test, and not the final version of the code.)
music.txt:
1
2
3
4
5
6
7
8
9
good
Derezzed
Daft Punk
TRON: Legacy
1:44
Mass
Virtual Boy
Symphony No. None
7:31
You defined entry_list_length and entry_list_current as

int entry_list_length;
int entry_list_current;


but in member function add_entry you are comparing them with the pointer NULL. So this code

1
2
3
4
if (database::entry_list_length == NULL || database::entry_list_current == NULL) {
	database::entry_list_length = 0;
	database::entry_list_current = 0;
}


is incomprehensible.

Here

database::entry_list[database::entry_list_current] = tempArray;

you are assigning the pointer of the first element of tempArray to the array entry_list but the array tempArray is a local array. So after exiting the function the pointer stored in entry_list will be invalid.

I think that it would be better if you would declare a vector instead of your array such a way

std::vector<std::vector<std::string>>

or at least use the following declaration of your array

std::string entry_list[maxEntries][4];
Last edited on
std::string tempArray [4] = {title,artist,album,length}; is created on stack so it is destroyed when the function exits. That's why your program crashes
Also, you don't need database:: prefix before variable names because add_entry() function is a part of database class.

And one more thing: you should use vectors instead of arrays. Vectors can be resized (while arrays can't) and you don't need to care about memory allocation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <vector>

struct db_entry
{
std::string title;
std::string artist;
std::string album;
std::string length;
};

// ...
class database {
// ...
	private:
		std::vector<db_entry> entry_list;
};




1
2
3
4
5
6
7
8
9
10
11
void database::add_entry(std::string title,std::string artist, std::string album,std::string length) {

db_entry de;

de.title=title;
de.artist=artist;
de.album=album;
de.length=length;

entry_list.push_back(de); // add entry to vector
}


(I haven't tested the code but I hope you get the idea)

http://cplusplus.com/reference/stl/vector/
Thanks, both of you. However,
#include <vector>

struct db_entry
{
std::string title;
std::string artist;
std::string album;
std::string length;
};

// ...
class database {
// ...
private:
std::vector<db_entry> entry_list;
};

in which file do i define db_entry?
Last edited on
std::string* entry_list [maxEntries];


I started to explain how to use this, but it's just not appropriate for your program. You know the maxEntries and the amount of strings in the entry, so thats that. I would do Vlad's last suggestion:

std::string entry_list[maxEntries][4];



database::entry_list[database::entry_list_current] = tempArray;

I would bet this is your problem. The memory for an array of string arrays hasn't been allocated, nor is it possible to say something like:
1
2
int x[4] = {1, 2, 3, 4};
int y[4] = x;

Something I would suggest:
1
2
3
4
5
6
7
8
9
10
11
struct Entry
{
  std::string title;
  std::string artist;
  std::string album;
  std::string length;
};


// In your class
Entry entry_list[maxEntries];

This gets rid of magic number "4", which is good.

in which file do i define db_entry?
in database.h
i've tried that, the compiler throws tons of errors.
nevermind, the errors were unrelated. I've fixed it, thanks for everyone's help.
Topic archived. No new replies allowed.