diff options
| author | Paulo Custodio <pauloscustodio@gmail.com> | 2021-02-04 23:58:19 +0000 |
|---|---|---|
| committer | Paulo Custodio <pauloscustodio@gmail.com> | 2021-02-04 23:58:19 +0000 |
| commit | a227cfcb4e5a2787be812731d430fe226cf1f373 (patch) | |
| tree | c088356b78f2498c173938a551bc1b4ad720078f | |
| parent | 26a1610b66c8206179a49cf7f090b785a4c13ebf (diff) | |
| download | perlweeklychallenge-club-a227cfcb4e5a2787be812731d430fe226cf1f373.tar.gz perlweeklychallenge-club-a227cfcb4e5a2787be812731d430fe226cf1f373.tar.bz2 perlweeklychallenge-club-a227cfcb4e5a2787be812731d430fe226cf1f373.zip | |
Fix C++ solution
store std::ifstream in a pre-aloocated array as storing pointers to
std::ifstream in an unordered_map was causing a heap corruption in
GCC - probably a compiler/stdlib bug
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | challenge-098/paulo-custodio/basic/ch-1.bas | 3 | ||||
| -rw-r--r-- | challenge-098/paulo-custodio/cpp/ch-1.cpp | 56 |
3 files changed, 34 insertions, 27 deletions
diff --git a/.gitignore b/.gitignore index b6dca4e062..ab8c2f5f55 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ *~ *.class *.exe +*.o +*.ali # Rust languageoutput directory target/ diff --git a/challenge-098/paulo-custodio/basic/ch-1.bas b/challenge-098/paulo-custodio/basic/ch-1.bas index b2c91ed2a5..4aa064ad66 100644 --- a/challenge-098/paulo-custodio/basic/ch-1.bas +++ b/challenge-098/paulo-custodio/basic/ch-1.bas @@ -64,6 +64,3 @@ do while command(i+1)<>"" print readN(command(i), val(command(i+1))) i=i+2 loop - - - diff --git a/challenge-098/paulo-custodio/cpp/ch-1.cpp b/challenge-098/paulo-custodio/cpp/ch-1.cpp index 03c59ae8a7..ef08e51794 100644 --- a/challenge-098/paulo-custodio/cpp/ch-1.cpp +++ b/challenge-098/paulo-custodio/cpp/ch-1.cpp @@ -16,53 +16,61 @@ Output: print readN("input.txt", 4); # returns "90" */ +#include <algorithm> +#include <array> #include <iostream> #include <fstream> #include <string> -#include <memory> -#include <unordered_map> +#include <cassert> #include <cstring> // store list of open files class Files { public: - Files() {} - virtual ~Files() { - for (auto& it : files) - delete it.second; - } - std::string readN(const std::string filename, int n) { - std::ifstream* ifs = add_file(filename); - char* buffer = new char [n+1]; - memset(buffer, 0, n+1); - ifs->read(buffer, n); + std::ifstream& ifs = add_file(filename); + char* buffer = new char[n + 1]; + memset(buffer, 0, n + 1); + ifs.read(buffer, n); auto text = std::string(buffer); delete[] buffer; return text; } private: - std::unordered_map<std::string, std::ifstream*> files; + // store std::ifstream in a pre-aloocated array as storing pointers to + // std::ifstream in an unordered_map was causing a heap corruption in + // GCC - probably a compiler/stdlib bug + static const int MAX_FILES = 20; + std::array<std::ifstream, MAX_FILES> files; + std::array<std::string, MAX_FILES> filenames; + size_t num_files{ 0 }; - std::ifstream* add_file(const std::string filename) { - auto found = files.find(filename); - if (found != files.end()) // found in map - return found->second; - else { // not found, must create new entry - auto ifs = new std::ifstream(filename); - if (!ifs->is_open()) { + std::ifstream& add_file(const std::string filename) { + auto end = filenames.begin() + num_files; + auto found = std::find(filenames.begin(), end, filename); + if (found != end) { // found in filename + size_t i = std::distance(filenames.begin(), found); + return files[i]; + } + else { // not found, must create new entry + if (num_files >= MAX_FILES) { + std::cerr << "too many files" << std::endl; + exit(EXIT_FAILURE); + } + filenames[num_files] = filename; + files[num_files].open(filename); + if (!files[num_files].is_open()) { std::cerr << "open file " << filename << " failed" << std::endl; exit(EXIT_FAILURE); } - files.emplace(filename, ifs); - return ifs; + return files[num_files++]; } } }; int main(int argc, char* argv[]) { Files f; - for (int i = 1; i+1 < argc; i+=2) - std::cout << f.readN(argv[i], atoi(argv[i+1])) << std::endl; + for (int i = 1; i + 1 < argc; i += 2) + std::cout << f.readN(argv[i], atoi(argv[i + 1])) << std::endl; } |
