I have come across the following error when I am compiling code. I have tried to look through my code to find the conversion error, but I don't see it.
The error occurs when compiling on compiles and runs on g++ (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5)
When I compile on Ubuntu, I get no errors and it runs. (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
This is the error.
/builddir/build/BUILD/gcc-8.3.1-20191121/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_string.h:1067: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator[](std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference = char&; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]: Assertion '__pos <= size()' failed.
Aborted (core dumped)
All of my header and class files.
Node.h
#ifndef NODE_HPP
#define NODE_HPP
#include <string>
class Node
{
private:
std::string value;
Node* next;
std::string password;
public:
Node();
Node(std::string value, std::string password);
std::string GetValue();
void SetNext(Node* next);
Node* GetNext();
std::string GetPW();
};
#endif
Node.cpp
#include "node.hpp"
#include <string>
//This creates an empty node, the constructor.
Node::Node()
{
this->value = "";
this->next = nullptr;
this->password = "";
}
//Creates a node with the passed variables
Node::Node(std::string value, std::string password)
{
this->value = value;
this->password = password;
this->next = nullptr;
}
//Returns the username.
std::string Node::GetValue()
{
return this->value;
}
//Sets the next node in the list.
void Node::SetNext(Node* next)
{
this->next = next;
}
//Returns the next node in the list.
Node* Node::GetNext()
{
return this->next;
}
//Returns the password of the current node.
std::string Node::GetPW()
{
return this->password;
}
hash.hpp
#ifndef HASH_HPP
#define HASH_HPP
#include <string>
#include "node.hpp"
#include "linked_list.hpp"
class Hash
{
private:
static const int tableSize = 29009;
int hashIndex(std::string);
LinkedList* hashTable[tableSize];
public:
Hash();
void insert(std::string username, std::string password);
bool search(std::string searchValue, std::string comparePW);
~Hash();
};
#endif
hash.cpp
#include "hash.hpp"
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
//Constructor that initiates each linked list in the hash table array.
Hash::Hash()
{
for (int x = 0; x < tableSize; x++)
hashTable[x] = new LinkedList;
}
//This places a node into the appropriate bucket in the has table.
void Hash::insert(std::string username, std::string password)
{
hashTable[hashIndex(username)]->InsertAtHead(username, password);
}
//Here is where the appropriate hash table is figured out.
int Hash::hashIndex(std::string key)
{
unsigned int index;
unsigned int keyLength = key.size();
for (unsigned int x = 0; x < keyLength; x++) {
index += (key[x] * index);
}
return index % tableSize;
}
//This returns true if the username exists in the directory and the password matches the entered password.
bool Hash::search(std::string searchValue, std::string comparePW)
{
std::string testString;
for (int x = 0; x < tableSize; x++)
{
if (hashIndex(searchValue)== x){
Node *temp = new Node;
temp = hashTable[x]->getHead();
while(temp != NULL){
if (searchValue.compare(temp->GetValue()) == 0)
{
if (comparePW.compare(temp->GetPW()) == 0)
return true;
}
temp = temp->GetNext();
}
}
}
return false;
}
Hash::~Hash()
{
LinkedList* temp;
for (int x = 0; x < tableSize; x++)
{
temp = hashTable[x];
temp->~LinkedList();
hashTable[x] = NULL;
}
}
linked_list.hpp
#ifndef LINKED_LIST_HPP
#define LINKED_LIST_HPP
#include <string>
#include "node.hpp"
class LinkedList
{
private:
Node* head;
public:
LinkedList();
void InsertAtHead(std::string value, std::string password);
Node* getHead();
~LinkedList();
};
#endif
linked_list.cpp
#include "linked_list.hpp"
#include <iostream>
//Starts the linked list by creating a head node.
LinkedList::LinkedList()
{
this->head = nullptr;
}
//Creates a new head for each item and places the old head as the following object.
void LinkedList::InsertAtHead(std::string value, std::string password)
{
Node* newNode = new Node(value, password);
newNode->SetNext(this->head);
this->head = newNode;
}
//Returns the current head node.
Node* LinkedList::getHead()
{
return this-> head;
}
//The destructor for the class
LinkedList::~LinkedList()
{
Node* temp = head;
while(temp != NULL)
{
Node* next = temp->GetNext();
delete temp;
temp = next;
}
}
main.cpp
#include <iostream>
#include <ostream>
#include <limits>
#include <fstream>
#include <ostream>
#include <time.h>
#include <stdio.h>
#include <iomanip>
#include "node.hpp"
#include "linked_list.hpp"
#include "hash.hpp"
using namespace std;
//I know I should have passed these to the appropriate functions, but I created global containers instead of passing them around.
LinkedList* listOfNames = new LinkedList();
Hash *myHashTable = new Hash();
//Here is where I can take a string and generate a pseudo-random password from it
std::string passGen(std::string user)
{
char passwordArray[9];
int achar;
srand (time(0));
for (int x=0; x <= 8; x++)
{
achar = (user[x] * (rand()%100))%26 + 97;
passwordArray[x] = (char)achar;
}
return passwordArray;
}
//This reads the filename that is passed in and builds the linked list of names and uses the password generator and generates passwords for each username.
void readFile(std::string newFile){
ifstream inFile(newFile);
std::string firstWord;
while(inFile >> firstWord)
{
listOfNames->InsertAtHead(firstWord, passGen(firstWord));
inFile.ignore(numeric_limits<streamsize>::max(), '\n');
}
inFile.close();
}
//Saves the plaintext username and password to a given filename.
void writeFile(std::string outFilename)
{
Node *temp = new Node;
temp = listOfNames->getHead();
ofstream outFile(outFilename);
while(temp != NULL)
{
outFile << std::left << setw(15) << temp->GetValue() << temp->GetPW() << std::endl;
temp = temp->GetNext();
}
outFile.close();
}
//This takes a string and encrypts it using the Vigenere Cipher and jones as the key
std::string encryptedString(std::string originalString)
{
std::string cipher;
std::string key = "jones";
for (int x = 0; x < 9; x++)
{
char i = ((originalString[x] + key[x%5]) %26);
i += 'a';
cipher.push_back(i);
}
return cipher;
}
//Takes the information from one file and saves it to a new file while encrypting all of the passwords.
void encryptFile(std::string fileName)
{
ifstream inFile("rawData.txt");
ofstream outFile("encrypted.txt");
std::string userName;
std::string passWord, encryptedPassword;
while(inFile >> userName >> passWord)
{
encryptedPassword = encryptedString(passWord);
listOfNames->InsertAtHead(userName, encryptedPassword);
outFile << std::left << setw(15) << userName << encryptedPassword << std::endl;
}
outFile.close();
inFile.close();
}
//Uses the information in a file to build a hash table
void fillHashTable()
{
ifstream inFile("encrypted.txt");
std::string username, password;
while(inFile >> username >> password)
{
myHashTable->insert(username, password);
}
inFile.close();
}
//The legal test showing 5 correct password matches when compared to items in my hash table
void legalTest()
{
ifstream inFile("rawData.txt");
std::string userName, passWord, matchResult;
std::cout << std::left << "Legal:\n";
std::cout << std::left << setw(10) << "Userid" << setw(10) << "Password" << "Result\n";
for (int x = 0; x < 5; x++)
{
inFile >> userName >> passWord;
std::string newPass = encryptedString(passWord);
if (myHashTable->search(userName, newPass))
matchResult = "match";
std::cout << std::left << setw(10) << userName << setw(10) << passWord << setw(10) << matchResult << std::endl;
}
inFile.close();
}
//A test that pulls the first 5 entries of my hash table and compares the password to incorrect matches
void illegalTest()
{
ifstream inFile("rawData.txt");
std::string userName, passWord, matchResult;
std::string key = "jones";
std::cout << std::left << "Illegal:\n";
std::cout << std::left << setw(10) << "Userid" << setw(10) << "Password" << "Result\n";
for (int x = 0; x < 5; x++)
{
inFile >> userName >> passWord;
passWord[0] = 'z';
std::string newPass = encryptedString(passWord);
if (myHashTable->search(userName, newPass))
matchResult = "match";
else
matchResult = "no match";
std::cout << std::left << setw(10) << userName << setw(10) << passWord << setw(10) << matchResult << std::endl;
}
inFile.close();
}
int main(){
readFile("lastNames.txt");
writeFile("rawData.txt");
encryptFile("encrypted.txt");
fillHashTable();
legalTest();
std::cout << std::endl;
illegalTest();
listOfNames->~LinkedList();
myHashTable->~Hash();
}
Makefile
CXX = g++
CXXFLAGS = -std=c++11 -Wall
OBJECTS = linked_list.o node.o hash.o
HEADERS = $(shell find . -path ./test -prune -o -name "*.hpp" -print)
main: main.o $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $@ $^
$(OBJECTS): $(HEADERS)
clean:
$(RM) *.o *.gch *.out core main test/TestCase