duplicate symbol error when compiling c++ code - c++

I'm trying to compile some c++ code on os x using g++ in the terminal. However, I keep getting an error and I'm unsure of what it means. I have 3 files, main.cpp; comp_fns.cpp and comp_fns.h. Window and Gene are two different classes. Here is the error:
g++ -Wall main.cpp comp_fns.cpp
duplicate symbol Window::setValues(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in:
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc51aFZg.o
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc2KNfcB.o
duplicate symbol Gene::setValues(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in:
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc51aFZg.o
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc2KNfcB.o
ld: 2 duplicate symbols for architecture x86_64
collect2: ld returned 1 exit status
Any help would be much appreciated, and I can post the code if needed.
EDIT: I did not #include one cpp file into another. Here is my header file, where I think the issue may be at. This is my first cpp program so there might be some obvious mistakes. I originally wrote it in C and am changing it over to c++ so I can learn how to do both.
#ifndef __Compare_Data_C____comp_fns__
#define __Compare_Data_C____comp_fns__
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
class Window {
public:
int start, stop, length;
double average;
string strandID, locations;
void setValues(string locs, string strand, string length, string avg);
};
class Gene {
public:
int start, stop;
string strandID, genes;
void setValues(string locs, string strand, string spcGene);
};
void Window::setValues(string locs, string strand, string a_length, string avg) {
locations = locs;
vector<string> token(3);
istringstream iss(locs);
for (int i=0; i<3; i++) {
getline(iss, token[i], '.');
}
start = atoi(token[0].c_str());
stop = atoi(token[2].c_str());
strandID = strand;
length = atoi(a_length.c_str());
average = atof(avg.c_str());
}
void Gene::setValues(string locs, string strand, string givenGene) {
vector<string> token(3);
istringstream iss(locs);
for (int i=0; i<3; i++) {
getline(iss, token[i], '.');
}
start = atoi(token[0].c_str());
stop = atoi(token[2].c_str());
strandID = strand;
genes = givenGene;
}
int getSize(string inputID, string strandID, const int header);
void getWindows(vector<Window> &win, string inputID, const int header);
void getGenes(vector<Gene> &posGene, vector<Gene> &negGene, string inputID, const int header);
void getSpecialWindows(vector<Window> &w, vector<Gene> &g, int wSize, int gSize, ofstream &output);
#endif /* defined(__Compare_Data_C____comp_fns__) */

Duplicate symbols means the linker faces the same function in both of your compilation units (main.cpp and comp_fns.cpp). Maybe you implemented the functions in the header without inline?

Related

C++ - function multiple definition of `Lexer::Tokenize

so I was trying to compile a file and I got this error(mingw-64):
C:\Users\me\AppData\Local\Temp\ccfdOWKk.o:EKLexer.cpp:(.text+0x0): multiple definition of `Lexer::Tokenize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
C:\Users\me\AppData\Local\Temp\cc9yNSun.o:EnderKnightShell.cpp:(.text+0x0): first defined here
C:\Users\me\AppData\Local\Temp\ccfdOWKk.o:EKLexer.cpp:(.text+0x36a): multiple definition of `Lexer::ProcessVariables(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
C:\Users\me\AppData\Local\Temp\cc9yNSun.o:EnderKnightShell.cpp:(.text+0x36a): first defined here
collect2.exe: error: ld returned 1 exit status
I've tried looking but there's none that seems to fit what issue I'm having(which seems to involve a function being used). I'm not much of a C++ person so I'm not sure what exactly is going on
EnderKnightShell.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "EKLexer.cpp"
#include <C:\EndorCore\EnderKnight Python Port\Full Language\C++ Compiler\Headers\PythonStatements.h>
using std::string;
using std::ifstream;
using std::vector;
using py::Python;
ifstream EnderScript("Test.ek");
int main() {
Lexer EkLexer;
Python python;
cout << "EnderKnight C++ Port Beta 1:" << endl;
for(string CodeLine; getline(EnderScript, CodeLine);){
EkLexer.Tokenize(CodeLine);
}
for (int i = 0; i < python.splitlines.size(); i++){
for (int j = 0; j < python.splitlines[i].size(); j++){
cout << python.splitlines[i][j] << endl;
}
}
}
EKLexer.cpp
class Lexer{
private:
typedef vector<map<string, string>> Tokens;
typedef vector<string> KeyWords;
Tokens tokens;
KeyWords keywords{
"echo",
"goto",
"stop",
"math",
"var",
"edef",
"end_edef",
"/*",
"if",
"end_if_state"};
public:
void Tokenize(string);
void ProcessVariables(string);
Python python;
};
void Lexer::Tokenize(string Code){
stringstream s(Code);
string temp;
while (s >> temp) {
if (temp.compare("echo") == 0) {
map<string, string> EchoMap {{"echo", Code}};
tokens.push_back(EchoMap);
}
else if (temp.compare("var") == 0) {
Lexer::ProcessVariables(Code);
}
// more code
void Lexer::ProcessVariables(string Code){
python.Split(Code, '=');
}
Thanks to templatetypedef's comment, I found that the issue was including a .cpp file. The solution is to use a header and cpp source file combo

Can't find cause of Invalid free() / delete / delete[] / realloc()

I am writing HTTP client in C++. When I was testing my program he crashed with this error:
*** Error in `./isabot': free(): invalid pointer: 0x00007ffe7f8d2600 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81299)[0x7fef1fd86299]
./isabot[0x408eca]
./isabot[0x409afe]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fef1fd27555]
./isabot[0x402d59]
======= Memory map: ========
.
.
.
I reran my program with valgrind -v and I got this error:
==20879== Invalid free() / delete / delete[] / realloc()
==20879== at 0x4C2B18A: operator delete(void*) (vg_replace_malloc.c:576)
==20879== by 0x408EC9: sendRequest(ssl_st*, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /homes/eva/xm/xmimoc01/ISA/isabot)
==20879== by 0x409AFD: main (in /homes/eva/xm/xmimoc01/ISA/isabot)
==20879== Address 0x1ffeffee00 is on thread 1's stack
==20879== in frame #1, created by sendRequest(ssl_st*, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (???:)
==20879==
When I started my program without valgrind, the program crashed on this. But, when I started my program with valgrind, it wrote to me an error and the program continued successfully without repetition this error.
My function sendRequest() looks like:
string sendRequest(SSL *ssl, int requestType, const string &botToken, const string &guildId, const string &channelId, const string &lastMessageId, const string &content)
{
const char *request;
string strRequest;
stringstream response;
string isChunked;
char buffer[BUFFER];
if (requestType == GET_CLIENT_ID) {
strRequest = createIDRequest(botToken);
}
else if (requestType == GET_GUILDS) {
strRequest = createGuildsRequest(botToken);
}
else if (requestType == GET_CHANNELS) {
strRequest = createChannelRequest(botToken, guildId);
}
else if (requestType == GET_MESSAGES) {
strRequest = createMessagesRequest(botToken, channelId);
}
else if (requestType == GET_ACTUAL_MESSAGES) {
strRequest = createActualMessagesRequest(botToken, channelId, lastMessageId);
}
else if(requestType == POST_SEND_MESSAGE) {
strRequest = createSendMessageRequest(botToken, channelId, content);
}
request = strRequest.c_str();
SSL_write(ssl, request, strlen(request));
while(true) {
memset(buffer, 0, sizeof(buffer));
int n = SSL_read(ssl, buffer, BUFFER);
if(n >= 0) {
buffer[n] = '\0';
}
if (n <= 5) {
break;
};
response << buffer;
if (isResponseChunked(response.str()) != true) {
break;
}
}
return response.str();
}
and I called it from main.cpp in part of code where it crashed like this:
string sendedMessage = sendRequest(conn.ssl, POST_SEND_MESSAGE, botToken, "", channelId, "", content);
buffer[n] = '\0'; will write past the end of buffer when n == BUFFER. This overwrites some part of the stack, likely snother local variable. If it is one of the string variables, the internal state is corrupted which could result in this error.
The simple fix is to allocate one additional character in buffer.
char buffer[BUFFER+1];
Alternatively, you could read one less byte in the call to SSL_read.

C++ Get length of const char* [ ] in vector [duplicate]

This question already has answers here:
How to get the real and total length of char * (char array)?
(15 answers)
Closed 4 years ago.
How do I get the length of const char* arrays indexes?
The vector:
std::vector<const char*> _infoBarText;
The const char* []:
const char* text[4] = {"Current T:", "Target T:", "Time elapsed:", "Time remaining:"};
Assigning the char array to the vector:
_infoBarText.assign(text, text+4);
How can I get the length of the individual strings, like "current T", from the vector?
Raw C strings (bare char*-s) are not a perfect fit for modern C++ code.
If you change it to std::vector<std::string_view> you get your problem solved without (virtually) any overhead (given you are initializing it with literals) and as a bonus you will potentially make it safer and more usable.
See the cppreference article for details.
Example (GodBolt):
#include <string_view>
#include <vector>
#include <iostream>
int main() {
using namespace std::literals;
std::vector<std::string_view> strs = { "hello"sv, "there"sv };
for (auto&& str: strs)
std::cout << str << str.size();
return 0;
}
GodBolt Code Insight Output (note the std::operator""sv("hello", 5ul)):
#include <string_view>
#include <vector>
#include <iostream>
int main()
{
using namespace std::literals;
std::vector<std::string_view> strs = std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > >{std::initializer_list<std::basic_string_view<char, std::char_traits<char> > >{std::operator""sv("hello", 5ul), std::operator""sv("there", 5ul)}, std::allocator<std::basic_string_view<char, std::char_traits<char> > >()};
{
std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > > & __range = strs;
__gnu_cxx::__normal_iterator<std::basic_string_view<char, std::char_traits<char> > *, std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > > > __begin = __range.begin();
__gnu_cxx::__normal_iterator<std::basic_string_view<char, std::char_traits<char> > *, std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > > > __end = __range.end();
for( ; __gnu_cxx::operator!=(__begin, __end); __begin.operator++() )
{
std::basic_string_view<char, std::char_traits<char> > & str = __begin.operator*();
std::operator<<(std::cout, std::basic_string_view<char, std::char_traits<char> >(str)).operator<<(str.size());
}
}
return 0;
}
The long way:
#include <vector>
#include <cstring> // for strlen
std::vector<const char*> _infoBarText;
char const *str = _infoBarText[0]; // or any other valid index
auto len = std::strlen(str);
Short:
auto len = std::strlen(_infoBarText[0]);

Hash map error: no match for call to ‘(const __gnu_cxx::

After compiling my hash_multimap I get this large one paragraph error for my
In member function ‘size_t __gnu_cxx::hashtable<
I have never seen this huge error and I'm actually not sure what to do to fix this error due to it's abnormal size.
Any suggestions why line:
p = map1.equal_range(searchKey);
is causing this abnormaly long error? FYI- I cut the whole error and removed the middle part because once I pasted it here it was like a page long O.o
ERROR
/usr/include/c++/4.3/backward/hashtable.h: In member function ‘size_t
__gnu_cxx::hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
_Alloc>::_M_bkt_num_key(const _Key&, size_t) const [with _Val =
std::pair<const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, Map2*>, _Key = std::basic_string<char
...
std::char_traits<char>, std::allocator<char> > >, _Alloc =
std::allocator<Map2*>]’
hash_map2.cpp:55: instantiated from here
/usr/include/c++/4.3/backward/hashtable.h:595: error: no match for call to
‘(const __gnu_cxx::hash<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > >) (const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&)’
Map.h file
#ifndef MAP2_H
#define MAP2_H
#include <iostream>
#include <string>
using namespace std;
class Map2 {
public:
Map2(string data1, string data2, string data3, string data4, string data5);
string pop, keyword, user, desc, id;
string get_pop() {return pop;}
string get_key() {return keyword;}
string get_user() {return user;}
string get_desc() {return desc;}
string get_id() {return id;}
void call_Values(int i);
};
Map2:: Map2(string data1, string data2, string data3, string data4, string data5) {
pop = data1;
keyword = data2;
user = data3;
desc = data4;
id = data5;
}
void Map2:: call_Values(int i) {
get_pop();
get_key();
get_user();
get_desc();
get_id();
}
#endif
hash_map2.cpp
#include <fstream>
#include <iostream>
#include "Map2.h"
#include <ext/hash_map>
#include <string>
#include <sstream>
using namespace std;
using __gnu_cxx::hash_multimap;
int nav() {
cout <<"Select from the following options : " << endl <<endl;
cout <<"Search Tweets based on Keyword (Type 1) " <<endl;
cout <<"End Program (Type 2)"<<endl<<endl;
int key =0;
cin >> key;
return key;
}
int main() {
int option = nav();
if (option == 1) {
ifstream readFile("project4.csv");
string tempPop, tempID, tempKey, tempUser, tempDesc;
string tempRead;
hash_multimap<string, Map2 *>map1;
while (readFile != NULL){
// sends to a temp variable
readFile >> tempRead;
for (int i =0; i<400; i++){
//create new object each time
Map2 *mapNode = new Map2(tempPop,tempID,tempKey,tempUser,tempDesc);
//insert each time new object is made
map1.insert(pair<string, Map2 *> (tempKey, mapNode));
} //end for
} //end while
//Navigation through multimap
//first pointer is for first one and second to last hash table value
pair<hash_multimap<string, Map2 *> :: const_iterator,
hash_multimap<string, Map2 *> :: const_iterator> p;
string searchKey = "";
cout << "Please enter the keyword value exactly so we can search the"<<
"available tweets: " <<endl;
cin >> searchKey;
p = map1.equal_range(searchKey);
}
else
return 0;
}
Issue is the fact of calling string to search. Need to convert the string to int before calling the value inside the equal_range function.

c++ map of vector in structure

The program I want to do is an anagram finder
From a dictionary file and a string input, the function "anagrams" should return me a vector (one for each size from 1 to max) of vector of words found in the dictionary that match all the combination of sub-words possible with input as anagram
When I create the new dictionary with the function createdictionary, I put every anagram in a vector of string
However, when I want to check for these anagrams in my anagrams function, I don't know how to access it (line 74)
In uniqueAnagram, I have every sub-anagram possible, everything is ok, but using
if (dict.words.find(it->second)){
cout << dict.words.find(it->second)->second[0] << endl;
}
in the loop (as a test to see if the expression actually write the right words) leads me to this error and I don't understand why:
In function 'std::vector, std::allocator >, std::allocator, > std::allocator > > >, std::allocator std::char_traits, std::allocator >, std::allocator std::char_traits, std::allocator > > > > > anagrams(const std::string&, const > Dictionary&, int)':|
error: could not convert 'dict->Dictionary::words.std::map<_Key, _Tp,
_Compare, _Alloc>::find [with _Key = std::basic_string, std::allocator >, _Tp =
std::vector,
std::allocator >, std::allocator, std::allocator > > >, _Compare =
std::less,
std::allocator > >, _Alloc = std::allocator
I've been stuck the last 10 hours on this and I can't take it anymore, I really don't know how to solve that issue
Thank for you help, you'd save me life
//anagrams.h
#ifndef ANAGRAMS_H_INCLUDED
#define ANAGRAMS_H_INCLUDED
#include <vector>
#include <string>
#include <map>
using namespace std;
struct Dictionary{
map<string, vector<string> > words;
};
Dictionary createdictionary(const string&);
vector<vector<string> > anagrams(const string&, const Dictionary&, int);
#endif // ANAGRAMS_H_INCLUDED
//anagrams.cpp
#include "anagrams.h"
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
string sortString(string input);
Dictionary createdictionary(const string& filename){
Dictionary dictionary;
ifstream ifs;
ifs.open(filename.c_str());
string word;
while (ifs >> word){
string sortedWord = sortString(word);
(dictionary.words[sortedWord]).push_back(word);
}
return dictionary;
}
string sortString(string input){
vector<char> vectorWord(input.begin(), input.end());
sort(vectorWord.begin(), vectorWord.end());
string sortedInput(vectorWord.begin(), vectorWord.end());
return sortedInput;
}
vector<vector<string> > anagrams(const string& input, const Dictionary& dict, int max){
vector<vector<string> > anagrams;
size_t n = input.length();
for (int r = 0; r < max + 1; r++){
vector<bool> v(n);
fill(v.begin() + r, v.end(), true);
map<string, string> uniqueAnagram;
do {
string word;
for (size_t i = 0; i < n; ++i) {
if (!v[i]) {
word = word + input[i];
}
}
word = sortString(word);
uniqueAnagram[word] = word;
} while (next_permutation(v.begin(), v.end()));
vector<string> tempAnagram;
for(map<string, string>::iterator it = uniqueAnagram.begin(); it != uniqueAnagram.end(); it++){
if (dict.words.find(it->second)){
cout << dict.words.find(it->second)->second[0] << endl;
}
}
sort(tempAnagram.begin(), tempAnagram.end());
anagrams.push_back(tempAnagram);
}
vector<char> vectorWord(input.begin(), input.end());
sort(vectorWord.begin(), vectorWord.end());
string sortedWord(vectorWord.begin(), vectorWord.end());
// cout << (dict.words.find(sortedWord)->second)[0] << endl;
return anagrams;
}
//main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "anagrams.h"
using namespace std;
int main()
{
string filename = "C:/dictionary.txt";
Dictionary dictionary = createdictionary(filename);
vector<vector<string> > anagram = anagrams("llohe", dictionary, 5);
return 0;
}
map::find returns an iterator, not a boolean. If the key wasn't found, it returns the map's past-the-end iterator. So instead of
if (dict.words.find(it->second))
you want
if (dict.words.find(it->second) != dict.words.end())
or
if (dict.words.count(it->second) != 0)
It would be more efficient to store the iterator so you don't need to find the key twice:
auto found = dict.words.find(it->second);
if (found != dict.words.end()) {
cout << found->second[0] << endl;
}