C++ Undefined Symbols for Architecture

I thought I'd finally got my code to compile and I was hit with this set of errors. I've looked into it, but I'm not sure what I'm missing from the definitions. My code is below, any point in the right direction would be very much appreciated.
1
2
3
4
5
6
7
8
9
10
11
12
13
Undefined symbols for architecture x86_64:
      "Flightlist::read_from_file(std::__1::list<Passenger, std::__1::allocator<Passenger> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
          _main in main-21bc64.o
      "Flightlist::check_reservation(std::__1::list<Passenger, std::__1::allocator<Passenger> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
          _main in main-21bc64.o
      "Flightlist::menu()", referenced from:
          _main in main-21bc64.o
      "Flightlist::insert(std::__1::list<Passenger, std::__1::allocator<Passenger> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
          _main in main-21bc64.o
      "Flightlist::remove(std::__1::list<Passenger, std::__1::allocator<Passenger> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
          _main in main-21bc64.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)



(database.h)
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
#include<list>
#include<algorithm>
#include<iostream>
#include<string>
#include<fstream>
#ifndef passenger_h
#define passenger_h
 using std::string;
 using std::cin;
 using std::cout;
 using std::list;
 using std::endl;

class Passenger {
public:
	Passenger(string, string, string);
	bool operator==(const Passenger&) const;
	bool operator<(const Passenger&) const;

	string fname, lname, destination;
	
};

class Flightlist {
public:
	int menu();
	void read_from_file(list<Passenger>&, string);
	void insert(list<Passenger>&, string, string, string);
	void remove(list<Passenger>&, string, string, string);
	bool check_reservation(list<Passenger>&, string, string, string);
	//void display_list(list<Passenger>&);
	//void save_to_file(list<Passenger>&, string)

	list<Passenger> flist;
};

#endif 



(database.cc)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "database.h"

Passenger::Passenger(string first, string last, string dest)
{
 	fname = first;
 	lname = last;
 	destination = dest;
}

bool Passenger::operator==(const Passenger& p) const
{
	return fname == p.fname && lname == p.lname;
}

bool Passenger::operator<(const Passenger& p) const
{
	return fname < p.fname || (fname == p.fname && lname < p.lname);
}

int menu()
{
	int option;
	cout << endl;
	cout << "Enter one of the following options:" << endl;
	cout << "1. load reservations from file:" << endl;
	cout << "2. reserve a ticket" << endl;
	cout << "3. cancel a reservation" << endl;
	cout << "4. check reservation" << endl;
	cout << "5. display passenger list" << endl; 
	cout << "6. save passenger list" << endl;
	cout << "7. exit" << endl << endl;
	cin >> option;
	cin.get();
	return option;
}

void Flightlist::read_from_file(list<Passenger>& flist, string filename)
{
	string fname, lname, destination;
	ifstream input(filename.c_str());
	while (input >> fname >> lname >> destination) 
	{					
		flist.push_back(Passenger(fname, lname, destination));
	}
	input.close();
}

void Flightlist::insert(list<Passenger>& flist, string fname, string lname, string destination)
{
	flist.push_back(Passenger(fname, lname, destination));
}

void Flightlist::remove(list<Passenger>& flist, string fname, string lname, string destination)
{
	flist.remove(Passenger(fname, lname, destination));
}

bool Flightlist::check_reservation(list<Passenger>& flist, string fname, string lname, string destination)
{
	list<Passenger>::iterator i1, i2;
	i1 = flist.begin();
	i2 = flist.end();
	return flist.end() != find(flist.begin(), flist.end(), Passenger(fname, lname, destination));
}

/*void display_list(list<Passenger>& flist)  (commented out because I haven't worked out how to do them yet)
{
	flist.sort();
	list<Passenger>::iterator i1, i2;
	i1 = flist.begin();
	i2 = flist.end();
	for ( ; i1 != i2; ++i1) {
		cout << *i1 << endl;
	}
}

void save_to_file(list<Passenger>& flist, string filename)
{
	flist.sort();
	list<Passenger>::iterator i1, i2;
	i1 = flist.begin();
	i2 = flist.end();
	ofstream output(filename.c_str());
	for ( ; i1 != i2; ++i1) {
		output << *i1 << " ";
	}
	output.close();
}
*/



(main.cc)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "database.h"

int main()
{	
	Flightlist flight_list;
	Passenger *p;

	while (true) 
	{
		switch (flight_list.menu())
		{
			case 1:	
				{
					flight_list.read_from_file(flight_list.flist, "ticket_reservations.dat");
					break;
				}

			case 2: 
				{
					cout << "first name of passenger:" << endl; 
					cin >> p->fname;
					cout << "last name of passenger" << endl;
					cin >> p->lname;
					cout << "destination of passenger" << endl;
					cin >> p->destination;
					flight_list.insert(flight_list.flist, p->fname, p->lname, p->destination);
					break;
				}

			case 3: 
				{
					cout << "first name of passenger:" << endl; 
					cin >> p->fname;
					cout << "last name of passenger" << endl;
					cin >> p->lname;
					cout << "destination of passenger" << endl;
					cin >> p->destination;
					flight_list.remove(flight_list.flist, p->fname, p->lname, p->destination);
					break;
				}

			case 4: 
				{
					cout << "first name of passenger:" << endl; 
					cin >> p->fname;
					cout << "last name of passenger" << endl;
					cin >> p->lname;
					cout << "destination of passenger" << endl;
					cin >> p->destination;
					if (flight_list.check_reservation(flight_list.flist, p->fname, p->lname, p->destination))
						cout << "this passenger has a ticket reservation" << endl;
					else
						cout << "this passenger does not have a ticket reservation" << endl;
					break;
				}

			/*case 5:	
				{
					display_list(flight_list.flist);
					break;
				}

			case 6: 
				{
					save_to_file(flight_list.flist, "ticket_reservations.dat");
				}
				break;
			*/

			case 7:
				return 0;
		}
	}
	
	return 0;
}


Sorry about the posting of so much code, I just am not sure what the errors relate to and I desperately need this code to compile. Thanks!
Two errors.
Missing std:: at line 40 database.cc
 
    std::ifstream input(filename.c_str());


Missing Flightlist:: at line 20 database.cc
 
int Flightlist::menu()
@Chervil good pick up on those, thanks! Although I'm still getting the same errors :/
It compiles for me. Did you include all the files (both main.cc and database.cc) when you compiled your project?
@Chervil that's so strange, I wish more than anything that it was compiling for me. I've both tried compiling straight from the main class and also using a makefile on both linux and an IDE, all of which give me this chunk of errors :/
Note, there is also a warning that pointer p is uninitialised in main().
@Chervil I updated my makefile (very silly error on my behalf there) and it compiles! Although yet to be able to run through it to test whether it even works (also still have to figure out the extra two functions). I've been pretty weary of that pointer, it was sort of put in as a last resort as nothing else would work (I thought I could just put Passenger p; and then use cin >> p.fname; for example. So I'm a little unsure of how to fix that warning :/
If I remove database.cc from the project, I too get a chunk of errors:
In function 'int main()':
[Warning] 'p' may be used uninitialized in this function [-Wmaybe-uninitialized]

In function `main':
undefined reference to `Flightlist::menu()'
undefined reference to `Flightlist::read_from_file(std::list<Passenger, std::allocator<Passenger> >&, std::string)'
undefined reference to `Flightlist::insert(std::list<Passenger, std::allocator<Passenger> >&, std::string, std::string, std::string)'
undefined reference to `Flightlist::remove(std::list<Passenger, std::allocator<Passenger> >&, std::string, std::string, std::string)'
undefined reference to `Flightlist::check_reservation(std::list<Passenger, std::allocator<Passenger> >&, std::string, std::string, std::string)'
[Error] ld returned 1 exit status
recipe for target 'flight.exe' failed


It looks like you're trying to compile just main.cc on its own.
@Chervil I finally ran the program and the menu came up like it should have, I chose to insert a passenger and as soon as I hit enter after the first name a segmentation fault occurred :/
Last edited on
Regarding the pointer p.
I was going to suggest putting Passenger p; and then changing the p->fname to p.fname and so on.


But now I start to look at the code, a lot of things don't make sense.

Instead of
flight_list.insert(flight_list.flist, p.fname, p.lname, p.destination);
it should simply be
flight_list.insert(p);

Or better, in main() where you get the user input, instead of directly accessing the member variables of the Passenger, fname, lname, destination, you could use three local variables and then use the passenger constructor, so that your code might look something like this:

1
2
    // Passenger p; // removed
    string fname, lname, dest;



1
2
3
4
5
6
7
8
9
10
11
    case 2: 
        {
            cout << "first name of passenger:" << endl; 
            cin >> fname;
            cout << "last name of passenger" << endl;
            cin >> lname;
            cout << "destination of passenger" << endl;
            cin >> dest;
            flight_list.insert(Passenger(fname, lname, dest));
            break;
        }
Last edited on
@Chervil oh, thank you so much! Would I not still need to have 'flist' in the list of arguments to match the functions in database.cc?
@Chervil I've attempted that code and just get numerous errors, eg. 'error: no matching function for call to Flightlist::insert(Passenger)' and 'candidate expects 4 arguments, 1 provided'.
Would I not still need to have 'flist' in the list of arguments to match the functions in database.cc?

Yes but No.
You don't need to pass flist as it is already a member variable of class Flightlist.

In fact you should make the member variables private in both your classes, like this:
1
2
3
4
5
6
7
8
9
class Passenger {
private:
    std::string fname, lname, destination;
        
public:
    Passenger(std::string, std::string, std::string);
    bool operator==(const Passenger&) const;
    bool operator<(const Passenger&) const;
};


1
2
3
4
5
6
7
8
9
10
11
12
13
class Flightlist {
private:
    std::list<Passenger> flist;   
     
public:
    int menu();
    void read_from_file(std::string);
    void insert(Passenger p);
    void remove(Passenger p);
    bool check_reservation(Passenger p);
    void display_list();
    //void save_to_file(string)
};

... and change the function definitions to match.

1
2
3
4
void Flightlist::insert(Passenger p)
{
	flist.push_back(p);
}
Last edited on
@Chervil I appreciate your help so much, I'm sorry to take up so much of your time.
These are my classes now, I'm getting a lot of errors and I'm just not sure where I'm going wrong from following your tips :/

(database.h)
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
#include<list>
#include<algorithm>
#include<iostream>
#include<string>
#include<fstream>
#ifndef passenger_h
#define passenger_h
 using std::string;
 using std::cin;
 using std::cout;
 using std::list;
 using std::endl;

class Passenger {
public:
    Passenger() {}
	Passenger(string, string, string);
	bool operator==(const Passenger&) const;
	bool operator<(const Passenger&) const;
private:
	string fname, lname, destination;
	
};

class Flightlist {
public:
	int menu();
	void read_from_file(string);
	void insert(Passenger p);
	void remove(Passenger p);
	bool check_reservation(Passenger p);
	//void display_list();
	//void save_to_file(string)
private:
	list<Passenger> flist;
};

#endif 


(database.cc)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "database.h"
Passenger::Passenger(string first, string last, string dest)
{
 	fname = first;
 	lname = last;
 	destination = dest;
}

bool Passenger::operator==(const Passenger& p) const
{
	return fname == p.fname && lname == p.lname;
}

bool Passenger::operator<(const Passenger& p) const
{
	return fname < p.fname || (fname == p.fname && lname < p.lname);
}

int Flightlist::menu()
{
	int option;
	cout << endl;
	cout << "Enter one of the following options:" << endl;
	cout << "1. load reservations from file:" << endl;
	cout << "2. reserve a ticket" << endl;
	cout << "3. cancel a reservation" << endl;
	cout << "4. check reservation" << endl;
	cout << "5. display passenger list" << endl; 
	cout << "6. save passenger list" << endl;
	cout << "7. exit" << endl << endl;
	cin >> option;
	cin.get();
	return option;
}

void Flightlist::read_from_file(string filename)
{
	string fname, lname, destination;
	std::ifstream input(filename.c_str());
	while (input >> fname >> lname >> destination) 
	{					
		flist.push_back(Passenger(fname, lname, destination));
	}
	input.close();
}

void Flightlist::insert(Passenger p)
{
	flist.push_back(p);
}

void Flightlist::remove(Passenger p)
{
	flist.remove(p);
}

bool Flightlist::check_reservation(list<Passenger>& flist, string fname, string lname, string destination)
{
	list<Passenger>::iterator i1, i2;
	i1 = flist.begin();
	i2 = flist.end();
	return flist.end() != find(flist.begin(), flist.end(), p);
}

/*void display_list(list<Passenger>& flist)
{
	flist.sort();
	list<Passenger>::iterator i1, i2;
	i1 = flist.begin();
	i2 = flist.end();
	for ( ; i1 != i2; ++i1) {
		cout << *i1 << endl;
	}
}

void save_to_file(list<Passenger>& flist, string filename)
{
	flist.sort();
	list<Passenger>::iterator i1, i2;
	i1 = flist.begin();
	i2 = flist.end();
	ofstream output(filename.c_str());
	for ( ; i1 != i2; ++i1) {
		output << *i1 << " ";
	}
	output.close();
}
*/


(main.cc)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "database.h"
int main()
{	
	Flightlist flight_list;
	string fname, lname, destination;

	while (true) 
	{
		switch (flight_list.menu())
		{
			case 1:	
				{
					flight_list.read_from_file(flight_list.flist, "ticket_reservations.dat");
					break;
				}

			case 2: 
				{
					cout << "first name of passenger:" << endl; 
					cin >> fname;
					cout << "last name of passenger" << endl;
					cin >> lname;
					cout << "destination of passenger" << endl;
					cin >> destination;
					flight_list.insert(Passenger(fname, lname, destination));
					break;
				}

			case 3: 
				{
					cout << "first name of passenger:" << endl; 
					cin >> fname;
					cout << "last name of passenger" << endl;
					cin >> lname;
					cout << "destination of passenger" << endl;
					cin >> destination;
					flight_list.remove(Passenger(fname, lname, destination));
					break;
				}

			case 4: 
				{
					cout << "first name of passenger:" << endl; 
					cin >> fname;
					cout << "last name of passenger" << endl;
					cin >> lname;
					cout << "destination of passenger" << endl;
					cin >> destination;
					if (flight_list.check_reservation(Passenger(fname, lname, destination)))
						cout << "this passenger has a ticket reservation" << endl;
					else
						cout << "this passenger does not have a ticket reservation" << endl;
					break;
				}

			/*case 5:	
				{
					display_list(flight_list.flist);
					break;
				}

			case 6: 
				{
					save_to_file(flight_list.flist, "ticket_reservations.dat");
				}
				break;
			*/

			case 7:
				return 0;
		}
	}
	
	return 0;
}
There are a couple of mismatches where the code was changed in one place but not in another.
File database.cc
Line 57
 
bool Flightlist::check_reservation(list<Passenger>& flist, string fname, string lname, string destination)
should be
 
bool Flightlist::check_reservation(Passenger p)


File main.cc
Line 13
 
flight_list.read_from_file(flight_list.flist, "ticket_reservations.dat");
should be
 
flight_list.read_from_file("ticket_reservations.dat");

I think that's it. I may have missed one, but that's the sort of problem.



@Chervil You are an absolute lifesaver. Genuinely thank you so much!
Once I figure out those two functions I'll be done, you've taken so much stress off me. Thanks so much!
Last edited on
No problem.
Topic archived. No new replies allowed.