1

I am trying to create a hash map to store characters from a string. I cannot seem to find the issue causing the error "3 [main] a 8724 cygwin_exception::open_stackdumpfile: Dumping stack trace to a.exe.stackdump". I believe it is somewhere in the hasher.cpp and has something to do with assigning values, but beyond that I am completely stumped. Any help would be much appreciated!

I've tried commenting out certain portions of the main.cpp. When I simply instantiate the hasher called "map", the code works. When I attempt to initialize or print, the error is thrown.

main.cpp:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include "hasher.h"
using namespace std;

int main(void){

  hasher *map = new hasher;
  map -> initialize(map);
  map -> printHash(map);

  return 0;
}

hasher.cpp:

  #include "hasher.h"
  #include <iostream>
  using namespace std;

  hasher::hasher(){

  }

  void hasher::initialize(hasher *h){ //initialize all charachters to spaces
    for(int i = 0; i < hasherSize; i++){
      h -> arr[i] -> C = ' ';
    }
  }

  void hasher::insert(hasher *h, char ins){
    int addr;
    int value = (int)ins; //value will be the ascii value of the char

    addr = value / 7; //map the current character to the ascii value mod 7

    node *curr = h -> arr[addr];
    while(curr -> next != nullptr){
      curr++;
    }
    curr -> next -> C = ins;
  }

  void hasher::del(hasher *h, char delChar){

  }

  bool hasher::inString(hasher *h, char se){

  }

  void hasher::printHash(hasher *h){
    for(int i = 0; i < hasherSize; i++){
      cout << h -> arr[i] -> C;
      node *curr = h -> arr[i];
      while(curr -> next != nullptr){
        curr++;
        cout << ", " << curr -> C;
      }
      cout << endl;
    }
  }

hasher.h:

#include "node.h"
#define hasherSize 40
using namespace std;

class hasher{
  public:
    node* arr[hasherSize];

    hasher();
    void initialize(hasher *H);
    void insert(hasher *H, char ins);
    void del(hasher *H, char del);
    bool inString(hasher *H, char searchChar);
    void printHash(hasher *H);
};

I believe all headers/data structures are correct (defined a node and a hash map that is an array of nodes, each node has a next pointer).

Thanks in advance for any help!

  • 1
    Why do you use pointers in these examples? And why do you have `hasher::initialize` instead of applying its logic to a constructor(`hasher::hasher`)? – Fureeish Jan 05 '19 at 16:31
  • I have added the hasher.h to the body of this post, I believe this makes the program work. If not, how should I change it? – Zach Warcola Jan 05 '19 at 16:49
  • I asked two questions in my comment and you answered neither of them – Fureeish Jan 05 '19 at 16:51
  • This looks like C code, not C++ code. (What may be good C code will likely be not idiomatic C++ code.) The `#include` should use the C++ versions of the C header, not the C headers directly. I don't see any reason to be using pointers. – Eljay Jan 05 '19 at 16:53
  • I use pointers because I pass each hasher object by reference. I am not sure why I would use (hasher::hasher), I do not exactly understand how that would change things. Sorry for the confusion! – Zach Warcola Jan 05 '19 at 16:53
  • "*I use pointers because I pass each hasher object by reference*" - emm... that does not compute... `C++` supports both *references* and *pointers* and **they are not the same thing**. You can read about their differences [here](https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in). Also, it appears that you don't know what a constructor is. From what book are learning `C++`? – Fureeish Jan 05 '19 at 16:55
  • 1
    `hasher::initialize` is stomping all over random memory. That's probably bad. – Eljay Jan 05 '19 at 16:58
  • @Fureeish I based this code off of a project I did over the fall for a university class. That project can be found here: [link](https://github.com/zwarcola/CSC-335/tree/master/SmallWorldTheory) . – Zach Warcola Jan 05 '19 at 16:58
  • One thing that I think should never appear in any C++ source code is this line: `using namespace std;` DEFINITELY should never be in a header file, even by those who advocate using them. – Eljay Jan 05 '19 at 17:00
  • @Eljay I had some issues with using that earlier but managed to work around it by using the name "hasher" instead of "hash". I am just trying to write some simple practice code to try and learn more. From now I will limit the use of 'using namespace std;'. – Zach Warcola Jan 05 '19 at 17:02
  • First of all - stop using pointers here. Nowhere in your code they are actually necessary. Second of all - the pointers are actually the source of your problem. As @Eljay mentioned, `hasher::initialize` works with `arr`, which is an array of pointers. They are **not initialized** and yet you try to access them. That's *undefined behaviour* and that's probably the reason of the crash. I will repeat this one again - stop using pointers in this code (and in general, unless you really need them). Places where you pass objects, use passing **by reference**, not **by pointer**. – Fureeish Jan 05 '19 at 17:04
  • 2
    @Fureeish Okay! Thank you for the advice! I apologize I am definitely newer to programming and general, all the advice appreciated! – Zach Warcola Jan 05 '19 at 17:07
  • As others have suggested, you have been taught C with a side order of classes. Important remedial reading: [What is meant by Resource Acquisition is Initialization (RAII)?](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii) and [What is The Rule of Three?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). You cannot write good quality, non-trivial C++ programs without understanding those two concepts. – user4581301 Jan 05 '19 at 17:16
  • Looking over the code at the given github repo I see `graph` member function definitions like `void printGraph(graph *G);`. Because this is a member function there will be a `this` parameter pointing at a `graph` instance. There is no need to pass in an additional `graph` instance unless you really need one instance of `graph` to have the ability to print a different instance of `graph` (eg `g.printGraph(&h);`). This would be odd. More likely `void printGraph();` is all you need and invoke it as `g.printGraph();`. – user4581301 Jan 05 '19 at 17:31
  • I recommend you supplement your knowledge of C++ with one or more of the [*Introductory, with previous programming experience* books from this list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Skip the basic books. It doesn't looks like you need to learn the general programming fundamentals, just more of the Whys and Wherefores of C++. – user4581301 Jan 05 '19 at 17:33

0 Answers0