Undefined reference error when compiling with g++ compiler in cygwin - c++

I'm just starting to work on a project for class and I'm getting an error that I'm unsure how to fix. I'll do my best to provide all necessary details but if you need any more info please let me know. The project is to create a simple hash function and I'm getting a linker error when trying to compile. I will post all of my code as well as the error I receive when compiling. I have taken two previous programming classes but that was quite a while ago and I'm pretty out of practice at the moment so it may be an obvious mistake. Ignore all commented out code in hash.h because that is just function definitions that my teacher provided that I have not yet implemented. She also specifically requested that we put our hashing function in its own separate file. I should also specify that I'm using a Windows machine with cygwin64 to compile my code.
hash.h:
#ifndef __HASH_H
#define __HASH_H
#include <string>
#include <list>
using std::string;
using std::list;
class Hash {
public:
void remove(string); // remove key from hash table
//void print(); // print the entire hash table
void processFile(string); // open file and add keys to hash table
//bool search(string); // search for a key in the hash table
//void output(string); // print entire hash table to a file
//void printStats(); // print statistics
private:
// HASH_TABLE_SIZE should be defined using the -D option for g++
//list<string> hashTable [HASH_TABLE_SIZE];
list<string> hashTable [100];
int collisions;
int longestList;
double avgLength;
int hf(string); // the hash function
void insert(string);
// put additional variables/functions below
// do not change anything above!
};
#endif
hash.cpp:
#include "hash.h"
void Hash::remove(string string_to_remove)
{
int index = hf(string_to_remove);
for(list<string>::iterator iter = hashTable[index].begin(); iter != hashTable[index].end(); iter++)
{
if(*iter == string_to_remove)
hashTable[index].erase(iter);
}
}
void Hash::insert(string string_to_add)
{
int index = hf(string_to_add);
hashTable[index].push_back(string_to_add);
}
void Hash::processFile(string file_name)
{
insert(file_name);
}
hash_function.cpp
#include "hash.h"
int Hash::hf(string input)
{
int sum = 0;
for (int i = 0; i < 5; i++)
sum += (int)input[i];
cout << sum % 100 << endl;
return [sum % 100 /*HASH_TABLE_SIZE*/];
}
Compiler Error:
$ g++ hash_function.cpp testmain.cpp hash.cpp -o test
/tmp/cc42z5XM.o:hash.cpp:(.text+0x32): undefined reference to `Hash::hf(std::string)'
/tmp/cc42z5XM.o:hash.cpp:(.text+0x32): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Hash::hf(std::string)'
/tmp/cc42z5XM.o:hash.cpp:(.text+0x13c): undefined reference to `Hash::hf(std::string)'
/tmp/cc42z5XM.o:hash.cpp:(.text+0x13c): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Hash::hf(std::string)'
collect2: error: ld returned 1 exit status

Related

How to inherit from an abstract class properly in C++?

I couldn't find a proper topic for this question as I haven't got a proper error message.
I'm trying to create a management system for a restaurant which mainly provides pizza as well as other foods(pasta, wings, etc). I want this system to be used by the staff. I have created an abstract class named Foods that can be used to inherit by other foods. So far I have created a class that inherits from Foods named Pizza. Below are my code.
PS: I have used namespaces for organize foods and staff members separately. As far as I know some people doesn't recommend namespace and my apologies if you're one of them.
interfaces.h
#include <vector>
#include <string>
namespace foods{
class Food{
double price;
// since the sauces and drinks are given with foods.
static const std::vector<std::string> sauces;
static const std::vector<std::string> drinks;
public:
virtual int retPrice() = 0;
virtual void ask() = 0; // ask user what to add
virtual ~Food() = default;
};
const std::vector<std::string> Food::sauces = {"Blue cheese", "Garlic", "Honey BBQ", "Marinara"};
const std::vector<std::string> Food::drinks = {"Pepsi", "Mountain Dew", "Coca Cola"};
class Pizza: public Food{
const double price;
const std::string pizzaType; // whether it is chicken, beef, etc.
const std::string size; // small, medium or large
int crust = 1; // how crust it is from 1-5
std::vector<std::string> toppings; // to store toppings
public:
Pizza(): price(15), pizzaType(" "), size(" "){}
int retPrice() override; // the price should change according to the type
void ask() override; // ask the customer for a pizza
void createACustom(); // create a custom pizza with desired toppings
};
};
functions.cpp
#include <iostream>
#include "interfaces.h"
namespace foods{
int Pizza::retPrice(){
return (price+5);
}
void Pizza::ask(){
std::cout << "Hello World!";
}
}
test.cpp
#include "interfaces.h"
int main(){
foods::Pizza* pizza = new foods::Pizza();
}
And I'm getting following error.
/usr/bin/ld: /tmp/ccQRR5B8.o: warning: relocation against `_ZTVN5foods5PizzaE' in read-only section `.text._ZN5foods5PizzaC2Ev[_ZN5foods5PizzaC5Ev]'
/usr/bin/ld: /tmp/ccQRR5B8.o: in function `foods::Pizza::Pizza()':
test.cpp:(.text._ZN5foods5PizzaC2Ev[_ZN5foods5PizzaC5Ev]+0x2b): undefined reference to `vtable for foods::Pizza'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
I tried using the keyword override and also made a default deconstructor, yet nothing seems working. I want to know what this error message means and a solution for this. In addition to that what is vtable?
Appreciate your time and answers.
EDIT 1
I have compiled it with g++ -Wall -Wextra test.cpp functions.cpp -o test, which is wrong and then I did g++ -Wall -Wextra test.cpp functions.cpp -o test and I'm getting following error.
/usr/bin/ld: /tmp/ccmv2G17.o:(.bss+0x0): multiple definition of `foods::Food::sauces[abi:cxx11]'; /tmp/ccuBNQjX.o:(.bss+0x0): first defined here
/usr/bin/ld: /tmp/ccmv2G17.o:(.bss+0x20): multiple definition of `foods::Food::drinks[abi:cxx11]'; /tmp/ccuBNQjX.o:(.bss+0x20): first defined here
collect2: error: ld returned 1 exit status
Why is it saying that it has multiple definitions?
You need to implement the static member variables sauces and drinks in functions.cpp and not in interfaces.h.
functions.cpp
namespace foods {
int Pizza::retPrice() {
return (price + 5);
}
void Pizza::ask() {
std::cout << "Hello World!";
}
// implement the static variables here.
const std::vector<std::string> Food::sauces = { "Blue cheese", "Garlic", "Honey BBQ", "Marinara" };
const std::vector<std::string> Food::drinks = { "Pepsi", "Mountain Dew", "Coca Cola" };
}
And remove them from interfaces.h.
If you implement them in interfaces.h they end up being implemented in each .cpp file that includes interfaces.h.
It's basically the same problem as if you define a global variable in a .h file.

C++ header files and error relocation truncated to fit

before I continue I'd like to tell you that I am new to programming (I've done a bit of python programming though but not that much).
I recently started learning C++ from YouTube videos and Sololearn.
I decided to start a project to train myself and I think that creating a python-like dictionary type is a good project (and maybe useful).
I created the Dictionary.h which contains the following code:
#ifndef DICTIONARY_H
#define DICTIONARY_H
class Dictionary { // Dictionary is a custom type that takes a key value(string required) and returns a value linked to it(int, string, bool are supported)
private:
std::list<std::string> keyList;
std::list<char> containerList; // I == int | S == string | B == bool
std::list<int> indexingList; // contains the index of each value
std::list<int> intVList;
std::list<std::string> strVList;
std::list<bool> boolVList;
// private function for getting the last index from a value list
int getLastIndex(char lType);
int getKeyIndex(std::string key);
char getContainerFromIndex(int indexNum);
int getIndexFromKeyIndex(int indexNum);
int _getValue(std::string key);
public:
// constructor
Dictionary();
// add element to the dictionary
void _add(std::string key, int value);
void _add(std::string key, std::string value);
void _add(std::string key, bool value);
// get element from the dictionary using the key value
int _get(std::string key);
// check if a key exists in the dictionary
bool keyInDict(std::string key);
};
#endif
and then I created the Dictionary.cpp with contains the following code (NOTE: the following is just a part of the code, have created all the mention functions from the header in the .cpp):
#include "Dictionary.h"
#include <iostream>
#include <string>
#include <list>
Dictionary::Dictionary() {
std::cout << "Hello World";
}
void Dictionary::_add(std::string key, int value) {
if (keyInDict(key)) {
throw 9403;
}
char containerChar = 'I';
keyList.push_back(key);
containerList.push_back(containerChar);
int atIndex = getLastIndex(containerChar);
indexingList.push_back(atIndex+1);
intVList.push_back(value);
}
int Dictionary::_getInt(std::string key) {
int keyI = getKeyIndex(key);
int realIndex = getIndexFromKeyIndex(keyI);
if (getContainerFromIndex(keyI) != 'I') {throw 9400;}
list<int>::iterator i = intVList.begin();
advance(i, realIndex);
return *i;
}
so I've written some code and now I want to test if it works so far (then I'll move forward to adding more functions.), so I created a run.cpp with the following content:
#include <iostream>
#include <string>
#include <list>
#include "Dictionary.h"
int main() {
Dictionary dict;
dict._add("test1", 1);
dict._add("test2", 5);
int got = dict._get("test1");
std::cout << got;
return 0;
}
but the compiler (CygWin g++ on windows 10 64 bit) throws this error:
$ g ++ run.cpp
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc7qwomO.o:run.cpp :(. text + 0x1e): undefined reference to `Dictionary :: Dictionary () '
/tmp/cc7qwomO.o:run.cpp:(.text+0x1e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Dictionary :: Dictionary () '
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc7qwomO.o:run.cpp :(. text + 0x58): undefined reference to `Dictionary :: _ add (std :: string, int) '
/tmp/cc7qwomO.o:run.cpp:(.text+0x58): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Dictionary :: _ add (std :: string, int) '
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc7qwomO.o:run.cpp :(. text + 0xab): undefined reference to `Dictionary :: _ add (std :: string, int) '
/tmp/cc7qwomO.o:run.cpp:(.text+0xab): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Dictionary :: _ add (std :: string, int) '
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc7qwomO.o:run.cpp :(. text + 0xf9): undefined reference to `Dictionary :: _ get (std :: string) '
/tmp/cc7qwomO.o:run.cpp:(.text+0xf9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Dictionary :: _ get (std :: string) '
collect2: error: ld returned output mode 1
#cause of my computer's language I had to pass the output through google translator so it may differ a bit from what you normally see
by the way, all files (Dictionary.h, Dictionary.cpp, run.cpp) are on the same directory
QUESTIONS
why do I get this error?
how can I fix it?
is there something I may not understand about including headers? do I need to link them with the cpp somehow?
ADDITIONAL INFO
I tried to edit the Dictionary.h and add the constructor body
(an empty body like {}) and the first error
about the Dictionary::Dictionary() did not appear(the rest appeared though).
my guess is: it doesn't read the Dictionary.cpp, cause if I edit the main to just std::cout << 5;
it works as expected (and in the error it says "undefined reference to ...")
The main file and the .cpp file must be linked before executing the main file. One solution is to create a makefile and run that.
or Try This
This line creates the .o files of the cpp files
g++ -c main.cpp Dictionary.cpp
This code link both the .o files together
g++ main.o Dictionary.o

ld returned 1 exit status w/ multiple definition of function

There's probably a 2 second solution to this but I've been trying to figure it out for the past hour and it's driving me crazy.
I'm trying to link together a .cpp and .h files into a main.cpp file, so it'd run there. But I get a multiple definition of every function inside my cpp file, which in causes "ld returned 1 exit status"
The more functions I add, the more errors I get.
Here's my code:
binaryHeap.h:
#ifndef Binary_H
#define Binary_H
#include <vector>
class BinaryHeap{
private:
std::vector <int> heap;
int left(int parent);
int right(int parent);
void heapifyUp(int index);
void heapifyDown(int index);
public:
BinaryHeap(); //Constructor
void insert(int element); //inserts element into heap
void deleteMin(); // deletes minimum element
int extractMin();
void displayHeap();
int size();
};
#endif //Binary_H
binaryHeap.cpp:
#include <iostream>
#include "binaryHeap.h"
BinaryHeap::BinaryHeap(){
}
void BinaryHeap::heapifyUp(int index){
int parent = (index - 1) / 2;
if(index != 0 && parent >= 0 && heap[parent] > heap[index]){
int temp = heap[index];
heap[index] = heap[parent];
heap[parent] = temp;
heapifyUp(parent);
}
}
void BinaryHeap::insert(int element){
heap.push_back(element);
heapifyUp(heap.size() - 1);
}
void BinaryHeap::displayHeap(){
std::vector<int>::iterator pos = heap.begin();
while (pos != heap.end()){
std::cout << *pos << std::endl;
pos++;
}
}
main.cpp:
#include "binaryHeap.cpp"
int main(int argc, char* argv[]) {
BinaryHeap h;
h.insert(5);
h.insert(2);
h.insert(19);
return 0;
}
And here's the errors:
main.o:main.cpp:(.text+0x0): multiple definition of
BinaryHeap::BinaryHeap()' binaryHeap.o:binaryHeap.cpp:(.text+0x0):
first defined here main.o:main.cpp:(.text+0x0): multiple definition of
BinaryHeap::BinaryHeap()' binaryHeap.o:binaryHeap.cpp:(.text+0x0):
first defined here main.o:main.cpp:(.text+0x20): multiple definition
of BinaryHeap::heapifyUp(int)'
binaryHeap.o:binaryHeap.cpp:(.text+0x20): first defined here
main.o:main.cpp:(.text+0xfe): multiple definition of
BinaryHeap::insert(int)' binaryHeap.o:binaryHeap.cpp:(.text+0xfe):
first defined here main.o:main.cpp:(.text+0x13e): multiple definition
of BinaryHeap::displayHeap()'
binaryHeap.o:binaryHeap.cpp:(.text+0x13e): first defined here
c:/program files
(x86)/dev-cpp/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe:
binaryHeap.o: bad reloc address 0x0 in section.pdata$_ZnwyPv'
collect2.exe: error: ld returned 1 exit status
C:\Users\~\Desktop\Coding Training\Binary Heap\Makefile.win:25: recipe
for target '"Binary' failed mingw32-make.exe: *** ["Binary] Error 1
Extending on my comment, you must never include a .cpp file in any other file. What #include does is copy all the contents from the included file into the place you are including it. This means that the contents of binaryHeap.cpp are compiled twice in your code. And this is what the errors are telling you.
To resolve errors in your case - in main.cpp, change the include to binaryHeap.h.
EDIT: Adding more explanation:
The include directive simply copies and pastes the source of the file to that spot. So, if you included binaryHeap.cpp in main.cpp, the source of binabyHeap is actually being compiled twice. And, once the linker starts combining your object files, it picks up multiple definitions of whatever you had in binaryHeap.cpp, and raises a few errors.

Undefined reference when using a function included in a header file [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I am experiencing something weird with my c++ source file or perhaps the compiler itself. It seems that when I attempt to compile the file, it hits me with a message -
undefined reference to "Basic_int_stack::Basic_int_stack()
undefined reference to "Basic_int_stack::Push(int)
Here is my code (I'm still a beginner so don't expect any crazy professional code )
Header file:
class Basic_int_stack
{
public:
// This part should be implementation independent.
Basic_int_stack(); // constructor
void push( int item );
int pop();
int top();
int size();
bool empty();
private:
// This part is implementation-dependant.
static const int capacity = 10 ; // the array size
int A[capacity] ; // the array.
int top_index ; // this will index the top of the stack in the array
};
Implementations:
#include "basic_int_stack.h"// contains the declarations of the variables and functions.
Basic_int_stack::Basic_int_stack(){
// the default constructor intitializes the private variables.
top_index = -1; // top_index == -1 indicates the stack is empty.
}
void Basic_int_stack::push( int item ){
top_index = top_index + 1;
A[top_index] = item ;
}
int Basic_int_stack::top(){
return A[top_index];
}
int Basic_int_stack::pop(){
top_index = top_index - 1 ;
return A[ top_index + 1 ];
}
bool Basic_int_stack::empty(){
return top_index == -1 ;
}
int Basic_int_stack::size(){
return top_index;
}
Main Function:
#include "basic_int_stack.h"
#include <iostream>
int main()
{
int var;
Basic_int_stack s1;
while((std::cin >> var)>=0){
s1.push(var);
}
return 0;
}
This is happening because you're building your main file without building and linking your class implementation file as well. You need to adjust your build settings somehow.
It is because you don't include Basic_int_stack.cpp when you complile.
Simplely speaking, when you encounter Undefined reference to xxx, it is a error generated by linker, when means the compliler can't find the implements. So you need check if you include the cpp file or dynamic library or static library.
I faced the same problem. Finally I found a fix by including .cpp file in the main file.
#include "file_name.cpp" //In the main file

g++ error: undefined reference while netbeans compiles in linux [duplicate]

This question already has answers here:
"undefined reference to" using 'g++' to compile a C++ program
(3 answers)
Closed 9 years ago.
Im using NetBeans IDE in linux mint for C++ programming. NetBeans compiles the code just fine but when i try to compile the main.cpp using g++ as in g++ main.cpp i get undefined reference errors:
I know there are many questions like this one and they the problem can be fixed by using the right -l library but I couldn't find any related to NetBeans/g++ and I couldn't figure how to overcome this problem.
Any help is appreciated.
Errors:
tmp/ccXSo5xI.o: In function `main':
main.cpp:(.text+0x82): undefined reference to `Hospital::Hospital(int, int, int)'
main.cpp:(.text+0xf3): undefined reference to `Resident::Resident(int, int)'
.
.
.
main.cpp
#include <iostream>
#include <cstdio>
#include "Resident.h"
#include "Hospital.h"
#include <stack>
using namespace std;
void readFromFiles(int [][10], int [][10]);
void readFromFiles(Hospital*[10], Resident*[10]);
void print10(int [][10], int [][10]);
void print10(Hospital*[10], Resident*[10]);
int main(void) {
int hospital[10][10] = {0};
int resident[10][10] = {0};
Hospital **hospitals = new Hospital*[10];
for(int i = 0 ; i < 10 ; i++)
hospitals[i] = new Hospital(3, i, 10); //3: quota, i: hospital number, 10:prefereneceLength
Resident **residents = new Resident*[10];
for(int i = 0 ; i < 10 ; i++)
residents[i] = new Resident(i,10); //i: hospital number, 10:prefereneceLength
.
.
.
Hospital.h
#ifndef HOSPITAL_H
#define HOSPITAL_H
#include "Resident.h"
using namespace std;
class Hospital {
public:
//constructors & destructors
Hospital();
Hospital(const int, const int, const int);
Hospital(const Hospital& orig);
virtual ~Hospital();
//getters & setters
int getNumber();
int getQuota();
int** getPreferenceList();
//member functions
void addPreference(const int, const int);
private:
int number;
int* preferenceList[2]; //1st row: preference order ; 2nd row: admission status
int quota;
Resident *admittedResidents;
};
#endif /* HOSPITAL_H */
Resident.h
#ifndef RESIDENT_H
#define RESIDENT_H
class Resident {
public:
//constructors & destructors
Resident();
Resident(const int, const int);
Resident(const Resident& orig);
virtual ~Resident();
//getters, setters
int getNumber();
int* getPreferenceList();
bool getAdmissionStatus();
//member functions
void addPreference(const int, const int);
private:
int number; //resident number
int proposalCount;
int* preferenceList; //not inverse, unlike Hospitals pref list
bool admissionStatus;
};
#endif /* RESIDENT_H */
I know that's a lot of code even though I shortened them, but I think they are the necessary parts. Thanks.
You need to include all source files:
g++ main.cpp hospital.cpp resident.cpp
g++ main.cpp will try to compile and link main.cpp into an executable (a.out). In the link stage, ld is not finding the symbols for the Hospital and Resident constructors while are called in main.cpp because they have not yet been compiled.
If you just want to compile main.cpp, use:
g++ -c main.cpp
You can link the object files later using:
g++ main.o hospital.o resident.o
If you want to compile and link the whole lot:
g++ main.cpp hospital.cpp resident.cpp