Trouble with error Undefined symbols.

Undefined symbols for architecture x86_64:
"entrance::rbt", referenced from:
entrance::delete_jobRBT(JobCreate) in entrance-a7ecc1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This is the error from terminal, cannot figure out, I set rat as a public static object for all class, but..

where insert is a attribute within the rbTree class, and it is working well.

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  
#include "JobCreate.h"
#include "rbTree.h"
#include "MinHeap.h"
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;

//static vector<JobCreate> *tempjoblist = new vector<JobCreate>;
//static vector<string> *original_comm = new vector<string>;
template <typename T>
class rbTree;

class MinHeap;

class JobCreate;

class command;

class processor;

class scheduler;

class entrance{
	friend class MinHeap;
	friend class JobCreate;
	friend class command;
	friend class processor;
	friend class scheduler;
	template <typename T> 
	friend class rbTree;
public:
	int time_clock;
	static MinHeap heap;
	static rbTree<JobCreate> rbt;
	//static Scheduler scheduler;
    //static Processor processor;
    //const static vector<command> *commands = new vector<command>;
	static vector<string> *original_comm;
	const static string outputpath;

	static bool createOutputFile(const string &path);

	MinHeap *newheap() { return new MinHeap(1000);}

	rbTree<JobCreate>  *newrbt() { return new rbTree<JobCreate>();}

	// scheduler newscheduler() { return new scheduler(); }

	// processor newprocessor() { return new processor(0, NULL);}

	static void input_to_file(const string &s);

	static void read_file( const string &path);

	static int get_time(const string &command);

	static string get_type ( const string &command );

	static vector<int> get_parameters( const string &command );

	static vector<string> split(string& str,const char* c);

	//command commandCreate( const string &origin );

	static string job_to_string(const JobCreate &job);

	static void insert_jobRBT(JobCreate job) {rbt.insert(job);}  ////prob

	JobCreate IDsearch(const int &jobid ){
		JobCreate temp(jobid, 0, 0);
		JobCreate res = rbt.search(rbt.root(), temp)->getKey();
		JobCreate null;
		if (res.equal(null)){
			return null;
		}
		else return res;
	}

	JobCreate NEXTsearch(const int &jobid ){
		JobCreate temp(jobid,0,0);
		JobCreate res = rbt.next(rbt.root(),temp);
		JobCreate null;
		if (res.equal(null)){
			return null;
		}
		else return res;
	}

	JobCreate PREVsearch(const int &jobid ){
		JobCreate temp(jobid,0,0);
		JobCreate res = rbt.previous(rbt.root(),temp);
		JobCreate null;
		if (res.equal(null)){
			return null;
		}
		else return res;
	}
};

vector<string>* entrance::original_comm = new vector<string>;
const string entrance:: outputpath ="output_file.txt";

bool entrance::
createOutputFile( const string &path ){
	ofstream file;
	file.open(path);
	if (!file.is_open()) return false;
	else return true;
	file.close();
}

void entrance::
input_to_file(const string &s){
	ofstream file;
	file.open(outputpath);
	if (file.is_open()) {
		file << s << "\r\n" <<endl;
	}
	file.close();
}

void entrance::
read_file( const string &path ){
	ifstream ifile;
	ifile.open(path);
	if (ifile.is_open()){
		string strline;
		while (getline(ifile, strline)){
			if (strline.empty())
				continue;
			//original_comm->append(strline);
			cout << strline << "\r\n" << endl;
		}
	}
	ifile.close();
}

int entrance::
get_time(const string &command){
	int index = command.find(":");
	string time = command.substr(0,index);
	istringstream iss(time);
	iss >> index;
	//cout << index << "\n" << endl;
	return index;
}

string entrance::
get_type ( const string &command ){
	int ind_begin = command.find(":") + 2;
	int ind_end	= command.find("(");
	string iss = command.substr(ind_begin,(ind_end-ind_begin));
	//cout << iss << "\n" << endl;
	return iss;
}

vector<int> entrance::
get_parameters( const string &command ){
	vector<int> ls; ////////
	int ind_begin = command.find("(") + 1;
	int ind_end = command.find(")");
	int tmp;
	string origin = command.substr(ind_begin, (ind_end - ind_begin));
	vector<string> temp;
	if ( origin.find(",") == -1 ){
		istringstream iss(origin);
		iss >> tmp;
		//cout << tmp <<"\n" << endl;
		ls.push_back(tmp);
		return ls;
	}
	else{
		temp = split(origin,",");
		for ( int i = 0; i < temp.size(); ++i ){
			istringstream iss(temp[i]);
			iss >> tmp;
			//cout << tmp <<"\n" << endl;
			ls.push_back(tmp);
		}
		return ls;
	}
}

vector<string> entrance::
split(string& str,const char* c)
{
    char *cstr, *p;
    vector<string> res;
    cstr = new char[str.size()+1];
    strcpy(cstr,str.c_str());
    p = strtok(cstr,c);
    while(p!=NULL)
    {
        res.push_back(p);
        p = strtok(NULL,c);
    }
    return res;
}

/*command entrance::
commandCreate( const string &origin ){
	int time = get_time(origin);
	string type = get_type(origin);
	vector<int> parameters = get_parameters(origin);
	command command = new command(time, type, parameters);   /////////
	return command;
	delete command;
}*/

string entrance::
job_to_string( const JobCreate &job ){
	string info; string tmp;
	info.append("("); 
	info.append(to_string(job._JobID));
	info.push_back(',');
	info.append(to_string(job._excecuted_t));
	info.append(","); 
	info.append(to_string(job._total_t));
	info.append(")\n");;
	//cout << info << endl;
	return info;
}

/*JobCreate entrance::
IDsearch( const int &jobid ){
	JobCreate temp(jobid, 0, 0);
	JobCreate res = rbt.search(rbt.root(), temp)->getKey();
	JobCreate null;
	if (res.equal(null)){
		JobCreate nul(0,0,0); return nul;
	}
	else return res;
}*/


int main(){
	entrance project;
	JobCreate job1(12, 2, 33);
	JobCreate job;
	project.createOutputFile(entrance::outputpath);
	project.newrbt();
	project.newheap();
	project.input_to_file("lalala");
	project.read_file("input_file.txt");
	project.get_time("10: Insert(1345,12)");
	project.get_type("10: Insert(1345,12)");
	project.get_parameters("10: Insert(1345,12)");
	project.job_to_string(job1);
	//project.IDsearch(12);
	project.insert_jobRBT(job1);
}
Last edited on
When you declare a static member variable it's just a declaration. You need to also define and initialize them outside the class definition, inside a source file.

header file
1
2
3
4
5
class entrance {
	// declarations 
	static MinHeap heap;
	static rbTree<JobCreate> rbt;
};

source file
1
2
3
// definitions 
MinHeap entrance::heap;
rbTree<JobCreate> entrance::rbt;


If you're using C++17 you can make it work simply by defining them as inline.

1
2
3
4
class entrance {
	static inline MinHeap heap;
	static inline rbTree<JobCreate> rbt;
};
Last edited on
Hi Peter, your reply makes my program work well, thank u very much.
Topic archived. No new replies allowed.