Compiler error undefined symbol - c++

I have simple class ina header file:
> cat Algorithms.hh
#ifndef Algorithms_hh
#define Algorithms_hh
#include<vector>
class Algorithms
{
public:
Algorithms();
void BubbleSort();
std::vector<int> myarray;
};
#endif
Then a corresponding c file:
> cat Algorithms.cc
#include <iostream>
#include <vector>
#include "Algorithms.hh"
Algorithms::Algorithms()
{
myarray.push_back(0);
}
void Algorithms::BubbleSort()
{
int i, j, flag = 1; // set flag to 1 to start first pass
int temp; // holding variable
int numLength = myarray.size();
for(i = 1; (i <= numLength) && flag; i++)
{
flag = 0;
for (j=0; j < (numLength -1); j++)
{
if (myarray[j+1] > myarray[j]) // ascending order simply changes to <
{
temp = myarray[j]; // swap elements
myarray[j] = myarray[j+1];
myarray[j+1] = temp;
flag = 1; // indicates that a swap occurred.
}
}
}
}
>
And then the main function:
> cat algo2.cc
#include <iostream>
#include <vector>
#include "Algorithms.hh"
using namespace std;
int main(int argc,char **argv)
{
Algorithms *arr=new Algorithms();
arr->myarray.push_back(1);
arr->myarray.push_back(2);
arr->myarray.push_back(100);
return 0;
}
>
When i compile the main:
I get the below error:
> CC algo2.cc
Undefined first referenced
symbol in file
Algorithms::Algorithms() algo2.o
ld: fatal: Symbol referencing errors. No output written to a.out
Can anyone tell me where i am wrong?

This is a linker error, the linker is telling you it can't find the definition of constructor of class Algorithms. You should compile with:
CC Algorithms.cc algo2.cc
You can identify it's a linker error because of the ld: in front of the error.
And of course as stated by Kerrek SB you need to declare your constructor without the Algorithms:: in front of it...

You've just forgotten to include both .cc files into compiling:
cc algo2.cc Algorithms.cc
If you include header file with declarations, like
#include "Algorithms.hh"
you should also provide implementation, definition in .c, or .lib. or load library with definition dynamically. In your case your library is Algorithms.cc, so just add it into compilation stage, and then both temporary object files
Algo2.a + Algorithms.a
will go to
a.out

Related

Undefined reference to 'HashTable::HashTable()'

I'm working on a testing program for a lab and I keep getting the error
[jereminp#bondi hw3]$ make insert_test
g++ -O3 -g -o insert_test.o -c insert_test.cc
g++ -O3 -g -o insert_test insert_test.o
insert_test.o: In function `main':
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:17: undefined reference to `HashTable::HashTable()'
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:24: undefined reference to `HashTable::insert(int)'
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:32: undefined reference to `HashTable::insert(int)'
collect2: ld returned 1 exit status
make: *** [insert_test] Error 1
I'm fairly certain I have the logic, but I can't get past this error and I feel like I'm missing something simple. Here's the parts of the code in question.
Makefile
CC = g++
CFLAGS =
COPTFLAGS = -O3 -g
insert_test: insert_test.o
$(CC) $(COPTFLAGS) -o $# $^
insert_test.cc
#include "HashTable.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class HashTable;
int main(int argc, char* argv[])
{
//checks .5 and .9 1x
int numRuns = 0;
int numProbes = 0;
int a=0;
HashTable h;
HashTable.hh
#ifndef HASHTABLE_H
#define HASHTABLE_H
class HashTable
{
public:
HashTable();
/* implement copy constructor, assignment, destructor if needed */
int hashfnc(int key);
int insert (int value);
/* insert the input value and return the number of probes
* return -1 if the table is full and insert fails */
bool find (int value, int& nProbes);
/* Search for the input value in table
* Return true if the search is successful, otherwise false
* Save # probes in 'nProbes' */
// getters
int capacity() { return nSlot; }
int size() { return nElem; }
double load_factor() { return load; }
int getSearchProbes() { return probesSearch; }
private:
/* declare your data */
double load; // track the load factor of table
int nSlot; // # slots i.e. max # elements can hold
int nElem; // current # elements in table
int arr[];
int probesSearch;
};
#endif
HashTable.cc
#include "HashTable.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class HashTable
{
public:
HashTable()
{
load = 0;
nSlot = 300;//nSlot is changable in order to optimize
nElem = 0;
arr = new int[nSlot];
probesSearch=0;
for(int i = 0;i<nSlot;i++)
{
arr[i] = NULL;
}
}
Some of the things I've tried are adding any and all includes I could think of, changing the last line shown in insert_test.cc to "HashTable h = new HashTable();"(where I got a different error), adding namespace std to the header. I feel like it should be a quick fix but at the same time I can't find the solution anywhere. Plz send help

gdb doesn't stop in a line with #include directive

The problem is that, when I set a breakpoint at the line of the #include, gdb just ignore the line and stop at the next instruction in the main (I compiled the main.cpp with g++ -g -O2 -std=c++11).
The program works perfect (-O2 doesn't affect the result at all), but I want to check what exactly does something inside that file, but I can't because gdb doesn't let me enter the code inside the file.
How can I debug code inside other file? Is it even possible?
Edit: Here is the code
main.cpp
#include <iostream>
#include <cstdlib>
#include <chrono>
#include "inc/includes.h"
template <class T>
void PrintVector(T* vector, int size){
for (int i=0; i<size; ++i){
std::cout << vector[i] << " ";
}
std::cout << std::endl;
}
template <class T>
void CheckTime(void (*f)(T*&, int), T* &vector, int size){
std::chrono::high_resolution_clock::time_point tantes, tdespues;
std::chrono::duration<double> transcurrido;
tantes = std::chrono::high_resolution_clock::now();
(*f)(vector, size);
tdespues = std::chrono::high_resolution_clock::now();
transcurrido = std::chrono::duration_cast<std::chrono::duration<double>(tdespues - tantes);
std::cout << size << " " << transcurrido.count() << std::endl;
}
int main(int argc, char * argv[]){
if (argc != 2){
std::cerr << "Formato " << argv[0] << " <num_elem>" << std::endl;
return -1;
}
int n = atoi(argv[1]);
int range;
#if defined RADIXSORTLSD || defined RADIXSORTMSD
unsigned short * array = new unsigned short[n];
range = (n<65536)?n:65536;
#else
unsigned int * array = new unsigned int[n];
range = n;
#endif
srand(time(0));
for (int i = 0; i < n; i++){
array[i] = rand()%range;
}
#ifdef PRINT
PrintVector(array, n);
#endif
#include "inc/select.h" //Here is the problem for debugging
#ifdef PRINT
PrintVector(array, n);
#endif
}
includes.h
#include "../src/radixsortlsd.cpp"
#include "../src/radixsortmsd.cpp"
#include "../src/mergesort.cpp"
#include "../src/bitonicsort.cpp"
#include "../src/insertion.cpp"
#include "../src/slowsort.cpp"
#include "../src/selection.cpp"
select.h This is the code I want to debug. I decided to separate it from the main because it will grow a lot.
// The calls to CheckTime takes the first parameter as the direction to a function, previously defined inside the cpps of includes.h
#ifdef RADIXSORTLSD
CheckTime(&RadixSortLSD, array, n);
#endif
#ifdef RADIXSORTMSD
CheckTime(&RadixSortMSD, array, n);
#endif
#ifdef MERGESORT
CheckTime(&MergeSort, array, n);
#endif
#ifdef INSERTION
CheckTime(&Insertion, array, n);
#endif
#ifdef SLOWSORT
CheckTime(&SlowSort, array, n);
#endif
#ifdef SELECTION
CheckTime(&Selection, array, n);
#endif
#ifdef BITONICSORT
CheckTime(&BitonicSort, array, n);
#endif
I hope this help. Note that everything compiles great and works great (I made sure that the macros I defined when compiling are the correct ones)
Note: By debugging (not the right word) I meant checking how a function works (a function I don't fully understand).
Possibly you could break at MyFunction(), then run 'bt' command to see the stack. Then you see, is there any additional stack frame or what stack frames consist of in terms of source files, it might help
First of all:
A include is a preprocessor directive which never generates code. Debuggers can stop only on things which can be executed. Including a file works during compilation, not during runtime.
The next:
Your included files will define some values, functions, classes and a lot other. So you must give the debugger an idea where to stop.
And at all:
Including 'cpp' files is really trash! There are only very seldom reasons to do this.
But ok, how to proceed:
If your header file ( or included cpp file ) provides a function, you simply can do a break Func and run your program. No need to open any file in a gui for gdb before.
If you want to look inside the included files, you also can list myheader.h:1. The 1 one is the line of code you want to start looking into the file.
And a hint: Please provide much smaller code examples which persons can compile for themselves to give you more detailed help. You example is really bad to understand!
Example session:
Header: f.h
#include <stdlib.h>
void g(void)
{
malloc(4000);
}
void f(void)
{
malloc(2000);
}
main.cpp:
#include "f.h"
int main(void)
{
int i;
int* a[10];
for (i = 0; i < 10; i++) {
a[i] = (int*)malloc(1000);
}
f();
g();
for (i = 0; i < 10; i++) {
free(a[i]);
return 0;
}
}
Example session:
> gdb prog
gdb) break f
Breakpoint 1 at 0x40061a: file main.cpp, line 10.
(gdb) run
Starting program: /home/xxx/go
Breakpoint 1, f () at f.h:10
10 malloc(2000);
(gdb) list
5 malloc(4000);
6 }
7
gdb )
Now you can walk through your subroutine with step.

How to fix architecture x86_64 errors?

I'm running omnet++ 4.6 for around 6months now. When I tried building my project after a few changes:
removing a header file from the project
adding more files to my includes folder
I get this error
Creating shared library: ../out/gcc-debug/src/libinet.dylib
Undefined symbols for architecture x86_64:
"BloomFilter::BloomFilter(unsigned long, int, unsigned long, ...)", referenced from:
AODVRouting::AODVRouting() in AODVRouting.o
AODVRouting::AODVRouting() in AODVRouting.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [../out/gcc-debug/src/libinet.dylib] Error 1
make: *** [all] Error 2
My project used to build and run fine before this.
This is .cc file:
#include "BloomFilter.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cstdarg>
#include <exception>
#include <stdio.h>
#include <string.h>
using namespace std;
#define SETBIT(a, n) (a[n/CHAR_BIT] |= (1<<(n%CHAR_BIT)))
#define GETBIT(a, n) (a[n/CHAR_BIT] & (1<<(n%CHAR_BIT)))
// The Constructor
BloomFilter::BloomFilter(size_t size,int hash_k, size_t nfuncs, ...) {
va_list l;
unsigned int n;
try {
this->a=new char[(size+CHAR_BIT-1)/CHAR_BIT];
}
catch(const std::exception& e)
{
// If we get here is that there is an allocation error .
// We must free the memory .
delete(this);
// std :: cerr << "ERROR: " << e.what () << endl;
// Then raise the exception to indicate that an error occurred.
throw;
}
try {
this->funcs= new hashfunc_t[nfuncs];
}
catch(const std::exception& e){
delete(this->a);
delete(this);
}
va_start(l, nfuncs);
for(n=0; n < nfuncs; ++n) {
this->funcs[n]=va_arg(l, hashfunc_t);
}
va_end(l);
this->nfuncs=nfuncs;
this->asize=size;
this->hash_k=hash_k;
}
// The Destructor
BloomFilter::~BloomFilter() {
/*
delete(this->a);
delete(this->funcs);
delete(this);
*/
}
int BloomFilter::AddToBloom(std::string word){
char t= '1';
int AddFlag; // to know if the element is added successfully
for(int i=0;i<this->hash_k;i++){
AddFlag=Add(word += t);
t++;
}
return AddFlag;
}
int BloomFilter::Add(std::string word){
size_t size = word.size() + 1;
char * buffer = new char[ size ];
strncpy( buffer, word.c_str(), size );
return Add(buffer);
}
int BloomFilter::Add(const char *s)
{
size_t n;
for(n=0; n<this->nfuncs; ++n) {
SETBIT(this->a, this->funcs[n](s)%this->asize);
}
return 0;
}
int BloomFilter::CheckBloom( std::string word){
int CheckFlag;
char t= '1';
for(int i=0;i<this->hash_k;i++){
if(!Check(word += t)) return 0;
t++;
}
return 1;
}
int BloomFilter::Check(std::string word){
size_t size = word.size() + 1;
char * buffer = new char[ size ];
strncpy( buffer, word.c_str(), size );
return Check(buffer);
}
int BloomFilter::Check(const char *s)
{
size_t n;
for(n=0; n< this->nfuncs; ++n) {
if(!(GETBIT(this->a, this->funcs[n](s)%this->asize))) return 0;
}
return 1;
}
//Print information about this object
void BloomFilter::toString(){
/*EV << "[BloomFilter] Hello, I am ready ? " << ready
<<" ; max entry :" << maxEntry << endl;*/
}
What's the fix for this error?
That's a linker, not a C++ compiler error. You will probably have to add the .o file generated from you .cc file to the list of objects that get linked together to form libinet.dylib
I got rid of this error after copying files .cc and .h from my root project to the project I'm working on (in the specified directory).
I did this while running omnet++ and within the projects browser.
I'm not sure how does that link to the "linker" problem but it definitely solved mine.

Struct defined in header and included in two source codes is only defined in one

I have a struct defined in a header file with three other files that #include that header file. One is another header(queue.h) file that defines a very basic hash table and the other two are source codes where one is defining the functions from the hash table header(queue.cpp) and the other contains main(p2.cpp).
The problem that I'm having is that the struct seems to work fine in p2.cpp but in queue.h the compiler is telling me that the struct is undefined.
Here is p2.h containing the struct definition.
#ifndef __P2_H__
#define __P2_H__
#define xCoor 0
#define yCoor 1
#include <iostream>
#include <string>
#include "queue.h"
#include "dlist.h" //linked list which I know works and is not the problem
using namespace std;
struct spot {
float key[2];
string name, category;
};
#endif /* __P2_H__ */
I have queue.h included in this header so that I only have to include p2.h in p2.cpp.
Here is p2.cpp
#include <iostream>
#include <string>
#include <iomanip>
#include "p2.h"
using namespace std;
int main () {
cout << fixed;
cout << setprecision (4);
Queue hashTable;
spot *spot1 = new spot;
spot1->key[xCoor] = 42.2893;
spot1->key[yCoor] = -83.7391;
spot1->name = "NorthsideGrill";
spot1->category = "restaurant";
hashTable.insert(spot1);
Dlist<spot> test = hashTable.find(42.2893, -83.7391);
while (!test.isEmpty()) {
spot *temp = test.removeFront();
cout << temp->key[xCoor] << " " << temp->key[yCoor] << " " << temp->name << " " << temp->category << endl;
delete temp;
}
return 0;
}
Places and item in the hash table and takes it back out.
Here is queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <iostream>
#include <string>
#include "dlist.h"
#include "p2.h"
using namespace std;
class Queue {
// OVERVIEW: contains a dynamic array of spaces.
public:
// Operational methods
bool isEmpty();
// EFFECTS: returns true if list is empy, false otherwise
void insert(spot *o);
// MODIFIES this
// EFFECTS inserts o into the array
Dlist<spot> find(float X, float Y);
// Maintenance methods
Queue(); // ctor
~Queue(); // dtor
private:
// A private type
int numInserted;
int maxElts;
Dlist <spot>** queue;
// Utility methods
//Increases the size of the queue.
void makeLarger();
int hashFunc(float X, float Y, int modNum);
};
#endif /* __QUEUE_H__ */
Here is queue.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include "queue.h"
using namespace std;
bool Queue::isEmpty() {
return !numInserted;
}
void Queue::insert(spot *o) {
if (numInserted >= maxElts) {
makeLarger();
}
int index = hashFunc(o->key[xCoor], o->key[yCoor], maxElts);
queue[index] -> insertFront(o);
}
Queue::Queue() {
numInserted = 0;
maxElts = 1000;
queue = new Dlist<spot>*[maxElts];
for (int i = 0; i < maxElts; i++) {
queue[i] = new Dlist<spot>;
}
}
Queue::~Queue() {
for (int i = 0; i < maxElts; i++) {
delete queue[i];
}
delete[] queue;
}
void Queue::makeLarger() {
Dlist <spot>** temp = queue;
queue = new Dlist <spot>*[maxElts*2];
for (int i = 0; i < maxElts*2; i++) {
queue[i] = new Dlist<spot>;
}
for (int i = 0; i < maxElts; i++) {
while (!temp[i] -> isEmpty()) {
spot *spotTemp = temp[i] -> removeFront();
int index = hashFunc(spotTemp->key[xCoor], spotTemp->key[yCoor], maxElts*2);
queue[index] -> insertFront(spotTemp);
}
}
for (int i = 0; i < maxElts; i++) {
delete temp[i];
}
delete[] temp;
maxElts *= 2;
}
int Queue::hashFunc(float X, float Y, int modNum) {
return ((int)(10000*X) + (int)(10000*Y))%modNum;
}
Dlist<spot> Queue::find(float X, float Y) {
Dlist<spot> result;
Dlist<spot> *temp = new Dlist<spot>;
int index = hashFunc(X, Y, maxElts);
while (!queue[index] -> isEmpty()) {
spot *curSpot = queue[index] -> removeFront();
if ((curSpot->key[xCoor] == X) && (curSpot->key[yCoor] == Y)) {
result.insertFront(new spot(*curSpot));
}
temp -> insertFront(curSpot);
}
delete queue[index];
queue[index] = temp;
return result;
}
I believe that the problem is in my queue.h file because it's where I get all of the errors like "spot has not been declared". Every time spot appears in queue.h I have at least one error. I searched around for anything like this but all I could find was people trying to share one instance of a struct across multiple source files, or the obvious question of putting a struct in a header and including that header across multiple source files(which is what I'm doing but my problem seems to be a rather unique one).
You are including queue.h within the header that actually defines spot, so by the point the file is actually included spot has not been defined yet.
For your scope guards, note that identifiers starting with a double underscore are reserved by the implementation, don't use them.
And this is a poor choice even in plain C:
#define xCoor 0
#define yCoor 1
use this instead:
enum {
xCoor = 0
, yCoor = 1
};
Ok first never ever using "using" clauses in header files (it destroys the purposes of namespaces)
2nd provide a complete example that fails to compile
In addition to what others have said, you also have a circular reference error, which can also lead to similar undefined symbol errors. You have queue.h include p2.h, which includes queue.h.

Using a namespace to make global functions, but getting multiply defined symbols error

These functions are Utility type things that most of my programs objects will use. I want to have them in a namespace and have them global. This namespace is defined in a header and then added to my precompiled header. However so far I have used the function from this namespace in 2 different objects and the compiler is throwing the multiply defined symbols error on these 2 objects.
namespace file
#ifndef UTILS_H
#define UTILS_H
#include <random>
#include <cmath>
namespace Utils
{
extern int GetRandomBetween(int low, int high)
{
if (low < 0 || low >= high)
return 0;
int seed = high - low;
return (rand() % seed) + low;
}
};
#endif
and my precomp header
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <random>
#define SAFE_DELETE( p ) { if( p ) { delete ( p ); ( p ) = NULL; } }
#define SAFE_DELETE_ARRAY( p ) { if( p ) { delete[] ( p ); ( p ) = NULL; } }
#define SAFE_RELEASE( p ) { if( p ) { ( p )->Release(); ( p ) = NULL; } }
// TODO: reference additional headers your program requires here
#include "Utils.h"
#include "Manager.h" // this object uses utils
#include "Bot.h" // this object uses utils
#include "LinkedList.h"
#include "Village.h" // this object will use utils in the future
The linker error message:
Manager.obj : error LNK2005: "int __cdecl Utils::GetRandomBetween(int,int)" (?GetRandomBetween#Utils##YAHHH#Z) already defined in Bot.obj
stdafx.obj : error LNK2005: "int __cdecl Utils::GetRandomBetween(int,int)" (?GetRandomBetween#Utils##YAHHH#Z) already defined in Bot.obj
c:\users\lee\documents\visual studio 2010\Projects\AI\Debug\AI.exe : fatal error LNK1169: one or more multiply defined symbols found
it also maybe worth noting that in my Manager class header I forward declared Bot. Same with Village class header.
Your function definition (ie: the source code) should not be in a header. The reason you are getting multiple definitions is that extern cannot convert a function definition (the source code) into a function declaration (ie: just the prototype). So you need to do this:
Util.h:
namespace Utils
{
int GetRandomBetween(int low, int high);
};
SomeSourceFile.cpp (probably Util.cpp):
namespace Utils
{
int GetRandomBetween(int low, int high);
{
if (low < 0 || low >= high)
return 0;
int seed = high - low;
return (rand() % seed) + low;
}
};
Alternatively, you can declare the function inline in the header:
namespace Utils
{
inline int GetRandomBetween(int low, int high)
{
if (low < 0 || low >= high)
return 0;
int seed = high - low;
return (rand() % seed) + low;
}
};
Though you should only use this for small functions.
Manager.cpp and Bot.cpp both include Util.h
Because of this, when they are compiled, both object files export the symbol "GetRandomBetween". When the linker goes to combine these object files into an executable, it finds 2 instances of the function. The linker can't determine which one to use (and it doesn't understand that they are identical).
If you want to make the object files NOT export the symbol (so that you dont have a linker conflict), remove the extern keyword.