This is a homework question. I am working on my Hash Table
assignment and I ran into some issues when trying to print the table.
Constraints:
- C++11
- No
std::map
orstd::unordered_map
Minimal Reproducible Example
#include <iostream>
#include <vector>
#include <atomic>
#include <ctime>
#include <iomanip>
#include <string>
class DataEntry {
public:
std::string get_date() { return date; }
std::string get_country() { return country; }
int get_c_cases() { return c_cases; }
int get_c_deaths() { return c_deaths; }
inline void set_date(std::string set_date) { this->date = set_date;};
inline void set_country(std::string set_country) { this->country = set_country;};
inline void set_c_deaths(int set_c_deaths) { this->c_deaths = set_c_deaths;};
inline void set_c_cases(int set_c_cases) { this->c_cases = set_c_cases;};
private:
std::string date;
std::string country;
int c_cases;
int c_deaths;
};
class CovidDB {
private:
std::vector<std::vector<DataEntry*>> HashTable;
int size = 17;
public:
void display_table();
bool add(DataEntry* entry);
int hash(std::string country);
};
int CovidDB::hash(std::string country) {
int sum = 0;
int count = 0;
for (char c : country) {
sum = sum + ((count + 1) * c);
count++;
}
return sum % size; //returns the hash
}
void CovidDB::display_table() {
for (const auto& vec : HashTable) {
for (const auto& entry : vec) {
if (entry != nullptr) {
std::cout << "[Date: " << entry->get_date() << "], "
<< "[Country: " << entry->get_country() << "], "
<< "[Cases: " << entry->get_c_cases() << "], "
<< "[Deaths: " << entry->get_c_deaths() << "]" << std::endl;
}
}
}
}
bool CovidDB::add(DataEntry* entry) {
time_t now = time(0);
tm* ltm = localtime(&now);
// DATE FORMAT: mm/dd/yy
std::string current_date_str = std::to_string(1 + ltm->tm_mon) + "/" + std::to_string(ltm->tm_mday) + "/" + std::to_string(ltm->tm_year % 100);
std::istringstream iss(current_date_str);
std::tm current_date = {};
iss >> std::get_time(¤t_date, "%m/%d/%y");
std::tm entry_date = {};
std::istringstream iss2(entry -> get_date());
iss2 >> std::get_time(&entry_date, "%m/%d/%y");
if (mktime(¤t_date) > mktime(&entry_date)) {
std::cout << "[Record rejected]" << std::endl;
return false;
}
int index = hash(entry -> get_country());
if (HashTable[index].empty()) {
HashTable[index].push_back((entry));
} else {
bool added = false;
for (DataEntry* existing_entry : HashTable[index]) {
std::atomic<bool> valid(false);
valid.store(hash(existing_entry->get_country()) == hash(entry->get_country()) &&
existing_entry->get_country() == entry->get_country());
if (valid) {
existing_entry->set_date(entry -> get_date());
existing_entry->set_c_cases(existing_entry->get_c_cases() + entry->get_c_cases());
existing_entry->set_c_deaths(existing_entry->get_c_deaths() + entry->get_c_deaths());
added = true;
delete entry;
break;
}
}
if (!added) {
HashTable[index].push_back(entry);
}
}
return true;
return true;
}
int main() {
CovidDB db;
// Create two DataEntry objects
DataEntry* entry1 = new DataEntry();
entry1->set_date("01/01/23");
entry1->set_country("Slovenia");
entry1->set_c_cases(1);
entry1->set_c_deaths(1);
DataEntry* entry2 = new DataEntry();
entry2->set_date("02/02/23");
entry2->set_country("Slovenia");
entry2->set_c_cases(1);
entry2->set_c_deaths(1);
// Add the entries to the CovidDB
db.add(entry1);
db.add(entry2);
// Display the table
db.display_table();
// Clean up memory
delete entry1;
delete entry2;
return 0;
}
The print function seems to work fine for 80% of the time (estimate), for instance when I am pushing data from .csv
file into the 2D vector and print it works fine, but when I try to group 2 entries of the same hash
eg:
Country: Slovenia
Date: 01/01/23
Cases: 1
Deaths: 1
Country: Slovenia
Date: 02/02/23
Cases: 1
Deaths: 1
It segfaults...I am aware that SEGFAULT
means one is trying to access memory that doesn't belong to him (usually trying to deref a nullptr
)
I tried loads of stuff before asking a question here:
Rubber duck Debugging
I noticed that the outer loop runs hash-1
times by putting std::court << "here";
in-between the loops, which means that something goes wrong when it comes to the index of the entry
.
I also changed auto
to std::vecotr<DataEntry*> vec
and to DataEntry*
since the outer vector is a vector of vectors and the inner vectors are vectors of DataEntry
pointers.
Debugging
I tried debugging the executable with gbd
, since I can't configure my Vs Code debugger, but it throws an error
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-211.el8.x86_64 libgcc-8.5.0-16.el8_7.x86_64 libstdc++-8.5.0-16.el8_7.x86_64
I googled it and the only solution I found was to root install these libraries, which I can't, since this is the school's server and running sudo
will get me kicked off.
I tried the XCode debugger but for some reason my code there runs differently...Could it be because the ssh
is Linux and the other one isn't?
Guards
I added "guards" to prevent printing an empty hash table, and a guard so that I'm not de-referencing a nullptr
, unfortunately, had no effect.
Aucun commentaire:
Enregistrer un commentaire