Visual C++ Linker Error 2019 - c++

I'm trying to include a simple hash table class in some files with a header class. But whenever I try to compile I get several errors like this:
LNK2019: unresolved external symbol " public: __thiscall HashTable::~HashTable(void)" (??1HashTable##QAE#XZ) referenced in function _main "
I'm using Visual Studio 2010. I am aware that this means it can't find the function definition in any of the source files. But I have defined them, in a file in the same directory as the file it's called in. Perhaps Visual Studio doesn't look in the current directory unless you set some linker option?
Here is the source code:
//HashTable.h
#ifndef HASH_H
#define HASH_H
class HashTable {
public:
HashTable();
~HashTable();
void AddPair(char* address, int value);
//Self explanatory
int GetValue(char* address);
//Also self-explanatory. If the value doesn't exist it throws "No such address"
};
#endif
//HashTable.cpp
class HashTable {
protected:
int HighValue;
char** AddressTable;
int* Table;
public:
HashTable(){
HighValue = 0;
}
~HashTable(){
delete AddressTable;
delete Table;
}
void AddPair(char* address, int value){
AddressTable[HighValue] = address;
Table[HighValue] = value;
HighValue += 1;
}
int GetValue(char* address){
for (int i = 0; i<HighValue; i++){
if (AddressTable[HighValue] == address) {
return Table[HighValue];
}
}
//If the value doesn't exist throw an exception to the calling program
throw 1;
};
};

No you have not. You created a new class.
The proper way to define the methods is:
//HashTable.cpp
#include "HashTable.h"
HashTable::HashTable(){
HighValue = 0;
}
HashTable::~HashTable(){
delete AddressTable;
delete Table;
}
void HashTable::AddPair(char* address, int value){
AddressTable[HighValue] = address;
Table[HighValue] = value;
HighValue += 1;
}
int HashTable::GetValue(char* address){
for (int i = 0; i<HighValue; i++){
if (AddressTable[HighValue] == address) {
return Table[HighValue];
}
}
//If the value doesn't exist throw an exception to the calling program
throw 1;
};

Related

: ld: fatal: symbol referencing errors [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Why can templates only be implemented in the header file?
(17 answers)
Closed 9 months ago.
I am facing the error as in below,
Undefined first referenced
symbol in file
void bcMwMrsh::cppListFromWire<CSSCODERec*>(void*&, RWTValSlist<CSSCODERec*, std::allocator<CSSCODERec*> >&, AISObject* (*)()) /app/sdasup/home/mhp/source/develop/sd/lib/libsdHostSupport.so
ld: fatal: symbol referencing error
Under bc/include/bcMwMrsh.h cppListFromWire defined as below, Please note I have declared and defined the cppListFromWire in .h
typedef AbcObject *(*factory)()
namespace bcMwMrsh
{
template<typename listT>
void cppListFromWire(void *&src,RWTValSlist<listT> &dest, factory);
}
template<typename listT>
void bcMwMrsh::cppListFromWire(void *&src, RWTValSlist<listT> &list, factory factoryFunc)
{LOG (LM_MARSHAL_COM, (" bcMwMrsh::cppAbcListFromWire()...\n"));
int nItems = 0;
ptrdiff_t* pstart = (ptrdiff_t*) src;
bcMwMrsh::cppIntFromWire(src, &nItems);
for (int i = 0; i < nItems; i++)
{
AbcObject *elem = factoryFunc();
assert (elem); // improper assert; should cause exception - KD
elem->fromWire(src);
list.append(elem);
}
LOG (LM_MARSHAL_COM, (" bcMwMrsh::cppAbcListFromWire(): length %i\n", ptrdiff_t((ptrdiff_t*)src - pstart)));
}
and under "wv/include/cppmarsh.h" cppListFromWire been defined as in below,
typedef AISObject *(*factorywv)();
namespace bcMwMrsh
{
template<typename listT>
void cppListFromWire(void *&src,RWTValSlist<listT> &dest, factorywv);
}
template<typename listT>
void cppListFromWire(void *&src,RWTValSlist<listT> &list, factorywv factoryFunc)
{
LOG (LM_MARSHAL_COM, (" cppmarsh::cppListFromWire()...\n"));
ptrdiff_t* pstart = (ptrdiff_t*) src;
short nItems=0;
bcMwMrsh::cppShortFromWire(src, &nItems);
for (int i=0; i < nItems; i++)
{
AISObject *elem = factoryFunc();
assert(elem); // improper assert; should cause exception - KD
elem->fromWire(src, 0);
list.append(elem);
}
LOG (LM_MARSHAL_COM, (" cppmarsh::cppListFromWire(): length %i\n",
ptrdiff_t((ptrdiff_t*)src - pstart)));
}
And the .so (/app/sdasup/home/mhp/source/develop/sd/lib/libsdHostSupport.so) path where the error is pointing out has cppListFromWire used at two files as in below,
under sd/sdHostSupport/csscode.cpp
#include "csscode.h"
#include "cppmarsh.h"
int CSSCODERecList::fromWire(void *&buf, long bufLen)
{
bcMwMrsh::cppListFromWire(buf, contents, CSSCODERec::AISFactory);
return 0;
}
and under sd/sdHostSupport/__cppmarsh.cpp
#include "cppmarsh.h"
void cppIntFromWire(void *&src, int *dest)
{
assert(sizeof(int)==4);
*dest=0;
#ifndef LITTLE_ENDIAN //NT Port
*((char*)dest+3)=*((char*)src);
*((char*)dest+2)=*((char*)src+1);
#else
*((char*)dest)=*((char*)src);
*((char*)dest+1)=*((char*)src+1);
#endif
(char*&)src+=2;
}
template<typename listT>
void cppListFromWire(void *&src,RWTValSlist<listT> &list, factorywv factoryFunc)
{
int nItems = 0;
cppIntFromWire(src, &nItems);
for (int i = 0; i < nItems; i++)
{
AISObject *elem = factoryFunc();
assert(elem); // improper assert; should cause exception - KD
elem->fromWire(src, 0);
list.append(elem);
}
}
Is this something related to function-overloading, as I can see cppListFromWire defined has one parameter with different return type? However I see that is falling under overloading rules. Anything that differs here please let me know.
I tried including signature in both the files didn't work. Also tried including absolute header paths didn't work. One thing that worked was when I commented out below line form the file sd/sdHostSupport/csscode.cpp but that vague thing one can do.
bcMwMrsh::cppListFromWire(buf, contents, CSSCODERec::AISFactory);
I am unable to figure out what's the problem and how to resolve that. Been stuck for about 2 weeks now. Any kind of help/suggestions/inputs are greatly appreciated.

C++, Weird behavior of cout when trying to print integers

Im trying to write a class that stores an id and a value in an container class.
Im using an nested class as my data structure.
When im compiling the code sometimes it prints perfectly, sometimes it prints nothing and sometimes it prints half of the data then stops.
When i debug the code the same weird behavior occours, when it fails during debug it throws an error "Map.exe has triggered a breakpoint.", the Error occours in the print method when im using cout.
cmap.h
#pragma once
class CMap
{
public:
CMap();
~CMap();
CMap& Add(int id, int value);
void print() const;
private:
class container
{
public:
~container();
int container_id = 0;
int container_value = 0;
};
container* p_komp_;
int dim_ = -1;
void resize();
};
cmap.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
CMap::CMap()
{
p_komp_ = new container[0];
}
CMap::~CMap()
{
p_komp_ = nullptr;
cout << "destroy cmap";
}
CMap& CMap::Add(int id, int value)
{
resize();
p_komp_[dim_].container_id = id;
p_komp_[dim_].container_value = value;
return *this;
}
void CMap::resize()
{
container* temp_array = new container[++dim_];
if (dim_ == 0)
{
temp_array[0].container_id = p_komp_[0].container_id;
temp_array[0].container_value = p_komp_[0].container_value;
}
for (unsigned i = 0; i < dim_; i++)
{
temp_array[i].container_id = p_komp_[i].container_id;
temp_array[i].container_value = p_komp_[i].container_value;
}
p_komp_ = temp_array;
}
void CMap::print() const
{
for (unsigned i = 0; i <= dim_; i++)
{
cout << p_komp_[i].container_id;
cout << p_komp_[i].container_value;
}
}
CMap::container::~container()
{
cout << "destruct container";
}
Map.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
void main(void)
{
CMap m2;
m2.Add(1, 7);
m2.Add(3, 5);
m2.print();
}
These two things are a possible reason for your problem:
int dim_ = -1;
and
container* temp_array = new container[++dim_];
When you allocate, you increase dim_ from -1 to 0. That is you create a zero-sized "array", where every indexing into it will be out of bounds and lead to undefined behavior.
You also have memory leaks since you never delete[] what you new[]. I didn't look for more problems, but there probably a more.
And an "array" (created at compile-time or through new[]) will have indexes from 0 to size - 1 (inclusive). You seem to think that the "size" you provide is the top index. It's not, it's the number of elements.
It seems to me that you might need to take a few steps back, get a couple of good books to read, and almost start over.

C++: Unresolved Externals in MP3 assignment

I'm working on a MP3 player for an assignment. I keep getting the following errors:
1>A4_main.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Song::ClearListFile(void)" (?ClearListFile#Song##SAXXZ) referenced in function "void __cdecl DeleteSong(void)" (?DeleteSong##YAXXZ)
1>A4_main.obj : error LNK2001: unresolved external symbol "public: static char * Song::songListFile_" (?songListFile_#Song##2PADA)
1>A4_Song.obj : error LNK2001: unresolved external symbol "public: static char * Song::songListFile_" (?songListFile_#Song##2PADA)
1>A4_Song.obj : error LNK2019: unresolved external symbol __imp__mciSendStringA#16 referenced in function "public: void __thiscall Song::PlaySong(void)" (?PlaySong#Song##QAEXXZ)
1>A4_Song.obj : error LNK2001: unresolved external symbol "public: static char * Song::currentMP3_" (?currentMP3_#Song##2PADA)
From what I understand, these sort of errors stem from not including function declarations, declaring but not implementing them, misspelling, etc. What have I missed here? Since this is an assignment, I'll post the bare minimum of the code I think is causing the problem.
A4_main.cpp
#include "A4_LinkedList.h"
#include "A4_Song.h"
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>
using namespace std;
LinkedList g_list;
void FreeLinkedList();
char DisplayMenu();
void LoadSongFile();
void AddNewSong();
void DeleteSong();
void PlaySong();
void PrintAllSongs();
//stuff
void LoadSongFile()
{
const int SZ = 256;
int songCnt = 0;
ifstream inData;
char buff[SZ];
Song* newSong;
_flushall();
cout << "\nEnter the full file path: ";
cin.getline(Song::songListFile_, SZ);
// Open the file
inData.open(Song::songListFile_);
// Free any memory currently allocated for the word array
FreeLinkedList();
// Loop through file again and allocate memory
while (!inData.eof())
{
// Each time through loop read all 5 entries in each line.
// Songt with the Song name
inData.getline(buff, SZ);
if (buff[0] == 0)
{
// No more words
break;
}
// Create a new Song object
newSong = new Song(buff);
if (newSong == 0)
{
cout << "\nDynamic memory allocation failed.";
break;
}
// Add this Song object to the linked list
g_list.AddLinkToBack(newSong);
songCnt++;
}
inData.close();
cout << "\nLoaded file and read " << songCnt << " Song objects.";
}
void DeleteSong()
{
const int SZ = 256;
bool foundSong = false;
Node* node = g_list.GetFirstNode();
Song* song = 0;
char songFileName[SZ];
_flushall();
// Prompt the user for the name of a song
cout << "\nEnter the song name with extension: ";
cin.getline(songFileName, SZ);
// Loop through the linked list for that song and delete it if it is found.
// If not, print error to console.
while (node != 0)
{
// Cast the void ptr to a song object ptr
song = (Song*)(node->data_);
// Call on the Song class to print the objects contents
if (strcmp(song->GetSongName(), songFileName) == 0)
{
// Set flag and get out of loop
g_list.RemoveThisLink(node);
foundSong = true;
break;
}
// Go to the next node
node = node->next_;
}
if (!foundSong)
{
cout << "\nCould not find that song in list!\n";
}
else
{
// Now that the linked list has been updated need to persist the new
// list to the song file, replacing previous contents.
Song::ClearListFile();
// Now loop through the linked list again, appending the song
// file name to the song list file.
node = g_list.GetFirstNode();
while (node != 0)
{
// Cast the void ptr to a song object ptr then add name to file
song = (Song*)(node->data_);
song->AppendToListFile();
// Go to the next node
node = node->next_;
}
}
}
A4_Song.cpp
#include "A4_Song.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <Windows.h>
using namespace std;
// Store the path name of the song list file
static char songListFile_[ENTRY_SZ] = "";
static char currentMP3_[ENTRY_SZ] = "";
// Static method to empty the song list file
static void ClearListFile()
{
ofstream outFile;
if (songListFile_[0] != 0)
{
// Open for truncate then close again
outFile.open(songListFile_, ios_base::ate);
outFile.close();
}
else
cout << "\nNothing to clear!";
}
void Song::PlaySong()
{
const int BUFF_SZ = 512;
char fullStr[BUFF_SZ];
MCIERROR err;
StopSong();
// Set global variable so we know this file is playing.
// Sandwich the file name in escaped double quotes so
// spaces can be included and don't need to double up
// on the backslashes.
sprintf_s(currentMP3_, ENTRY_SZ, "\"%s\"", songPath_);
sprintf_s(fullStr, BUFF_SZ, "open %s type mpegvideo alias myFile", currentMP3_);
err = mciSendString(fullStr, NULL, 0, 0);
err = mciSendString("play myFile", NULL, 0, 0);
}
Let me know if I've omitted too much.
Your problem is that you have variables and functions declared inside Song, but are defined at namespace level. This makes them different entities, and so definitions for the declarations in Song are never found.
static char songListFile_[ENTRY_SZ] = "";
static char currentMP3_[ENTRY_SZ] = "";
static void ClearListFile() {/*...*/}
These should be changed. Removing static and prefixing the surrounding class Song should fix it.
char Song::songListFile_[ENTRY_SZ] = "";
char Song::currentMP3_[ENTRY_SZ] = "";
void Song::ClearListFile() {/*...*/}
You only need the static inside the class definition. Outside it, you're using a different meaning of the static keyword. I think you have more instances like this outside the code you posted, but it shouldn't be difficult to find them.

Double function segmentation fault on return to double

I have a double function
double Grid::getAverageNeighborhoodFitnessEvaluation(int agentPositionX, int agentPositionY)
{
GetNeighbourhood(agentPositionX, agentPositionY,neighborhoodEvaluations);
int neighborscount = 0;
double fitnesssum = 0;
double neighborfitness;
double value;
for (size_t i = 0; i < neighborhoodEvaluations.size(); ++i)
{
if ((*(neighborhoodEvaluations.at(i))) != NULL)
{
neighborfitness = (*(neighborhoodEvaluations.at(i)))->GetFitness();
if(neighborfitness<0)
neighborfitness=0;
fitnesssum+=neighborfitness;
neighborscount++;
}
}
value = fitnesssum/neighborscount;
return value;
}
GetNeighbourhood assigns an array of a defined type (Agent) to neighborhoodEvaluations
*(neighborhoodEvaluations.at(i)))->GetFitness(); returns a double that represents a value for that point in the array. These have all been used previously with no issues.
When called from my main (where RealX and RealY are two integers)
int currentFitness = getAverageNeighborhoodFitnessEvaluation(RealX,RealY);
always works
double currentFitness = getAverageNeighborhoodFitnessEvaluation(RealX,RealY);
causes Segmentation fault
Does anyone know what possibilities could result in this and/or what value an int can take but a double can't seem to?
So far i have traced the error to our Agent implementation
Agent.cpp
#include "Agent.h"
Agent::Agent(void)
{
m_age = 0;
m_fitness = -1;
}
Agent::~Agent(void)
{
}
int Agent::GetAge()
{
return m_age;
}
double Agent::GetFitness()
{
return m_fitness;
}
void Agent::IncreaseAge()
{
m_age++;
}
AgentType Agent::GetType()
{
return m_type;
}
Agent.h
#ifndef AGENT_H
#define AGENT_H
enum AgentType { candidateSolution, cupid, reaper, breeder};
class Agent
{
public:
Agent(void);
virtual ~Agent(void);
double GetFitness();
int GetAge();
void IncreaseAge();
AgentType GetType();
virtual void RandomizeGenome() = 0;
protected:
double m_fitness;
AgentType m_type;
private:
int m_age;
};
#endif // !AGENT_H
Can't seem to locate the exact problem though
From your comment on the gdb debugger answer, I see that you are calling the GetFitness method on a null object (Agent::GetFitness (this=0x0)). This means that neighborhoodEvaluations.at(i) is returning a null-pointer. at() only checks for out of bounds, but if what was put into the array to begin with is a null pointer, at() won't help you. To guard agains this, you should change
if ((*(neighborhoodEvaluations.at(i))) != NULL)
into
if (neighborhoodEvaluations.at(i) != NULL)
If neighborhoodEvaluations is not supposed to contain null pointers, you will have to track down why getNeighborhood() is putting them there. Perhaps you are looking for out-of-bound neighbors for the elements at the edge of your set of points?
Quickly get started on gdb debugger using this article http://www.cs.cmu.edu/~gilpin/tutorial/ . Then tell us which line produces the segmentation fault .

LNK2019 error, unresolved external symbol

The error verbatim reads
1>yes.obj : error LNK2019: unresolved external symbol "int __cdecl availableMoves(int * const,int (* const)[4],int)" (?availableMoves##YAHQAHQAY03HH#Z) referenced in function "void __cdecl solveGame(int * const,int (* const)[4])" (?solveGame##YAXQAHQAY03H#Z)
I've never seen this error before. Here are the two functions I believe it's referring to though.
int availableMoves(int a[15], int b[36][3],int openSpace){
int count=0;
for(int i=0; i<36;i++){
if(i < 36 && b[i][2] == openSpace && isPeg(b[i][0],a) && isPeg(b[i][1],a) ){
count++;
}
}
return count;
}
and
void solveGame(int a[15], int b[36][4]) {
int empSpace;
int movesLeft;
if(pegCount(a) < 2) {
cout<<"game over"<<endl;
} else {
empSpace = findEmpty(a);
if(movesLeft = availableMoves(a,b,empSpace) < 1 ) {
temp[index] = empSpace;
d--;
c[d][0] = 0;
c[d][1] = 0;
c[d][2] = 0;
c[d][3] = 0;
a[b[c[d][3]][0]] = 1;
a[b[c[d][3]][0]] = 1;
a[b[c[d][3]][0]] = 0;
b[c[d][3]][3] = 0;
index++;
} else if(movesLeft >= 1) {
chooseMove( a, b, empSpace);
index = 0;
for(int i=0; i<4; i++) {
temp[i] = -1;
}
}
d++;
solveGame( a, b);
}
}
Your current declaration doesn't match the definition.
You probably have declared the function availableMoves() before you use it, but then you implement a different function:
int availableMoves(int* const a, int (* const)[4] , int);
//....
//....
//....
//code that uses available moves
int availableMoves(int a[15], int b[36][3],int openSpace)
{
//....
}
Since the compiler sees that declaration first, it will use it to resolve the call in the block of code. However, that function is not exported, as it has a different signature.
in solved game
b[36][4]
in available moves
b[36][3]
that could create a problem.
Nice one: you use incompatible array dimensions! Note that part of the error message reads
availableMoves(int *const,int (*const)[4],int)
While the definition of availableMoves() looks like this:
int availableMoves(int a[15], int b[36][3],int openSpace)
Although the first dimension of the arguments is ignored, all other dimensions have to match exactly. You try to call this function with incompatible dimensions, however:
void solveGame(int a[15], int b[36][4]){
...
... availableMoves(a,b,empSpace) ...