-3

Cant figure out where my logic is going wrong when trying to add a node to the front of the linked list. The progarm is allowing for dual inputs and repeats nodes. Be looking at the logic for a while now and keep seem to nail down where I am going wrong. The issue must be simple, and im over looking it. Seems to keep adding it to the same linked_list instead of each users different list Inputs that cause the are are P Sam P Liza P Mark P Amy F Liza Amy F liza Mark F Amy Sam

After executing that the issue is really clear

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstring>

using namespace std;
void menu_function(void);
void command_execute( string command, string name1, string name2);
int hash_function(string str);
void insert_into_hashtable( int ascii_total, string name);
void add_friendship( int ascii_key, string name );
void print_friendships( int aascii_key);
void check_friendship( int ascii_key, string name);
void remove_friendship( int ascii_key, string name );

#define SIZE 150

struct friend_list
{
    string name;
    struct friend_list* next;
};

typedef struct friend_list list;

struct user{
    string name;
    int key;
    friend_list* FriendList;
};

struct user* hashArray[SIZE];

int main(int argc, const char * argv[]) {
    menu_function();
    return 0;
}
void menu_function(){
    char user_input[100];//this could limit the size of input
    string command;
    string name1 = "\0";
    string name2 = "\0";;
    char* token;
    int inputsize = 100;
    int i = 0;
    char delimit[]=" \t\r\n\v\f";
    while( 1 )
    {
        printf("\nP <Name> to create a person\n");
        printf("F <Name> <Name> record friendship\n");
        printf("U <Name> <Name> terminate friendship\n");
        printf("L <Name> print out friends of a specified person\n");
        printf("Q <Name> <Name>  check friendship status of two people\n");
        printf("X - terminate the progarm\n");
        // Determine user input and
        fgets(user_input, inputsize, stdin);
        //getline(&input, &inputsize, stdin);//takes in user input;
        //parsing e string for the data within
        token = strtok( user_input, delimit);
        i = 0;
        while( token != NULL ){
            if(i == 0)
            {
                command = token;
                //cout<< command<<endl;
            }
            if(i == 1)
            {
                name1 = token;
                // cout<< name1<<":"<<endl;
            }
            if( i == 2 )
            {
                name2 =  token;
                //  cout<< name2<<":"<<endl;
                name1 = name1 + "\n";
            }
            token = strtok( NULL, " " );
            i++;
        }
        command_execute( command, name1, name2);
        command = '\0';
        name1 = '\0';
        name2 = '\0';
    }
}
void command_execute( string command, string name1, string name2)
{
    //cout<<"command is: "<<command<<endl;
    switch( command[0])
    {
        case 'P': //Create record of the person
            insert_into_hashtable( hash_function(name1), name1);
            break;
        case 'F': //Record friendship
            add_friendship(hash_function(name1), name2);
            add_friendship(hash_function(name2), name1);
            break;
        case 'U': //Terminate Friendship
            remove_friendship( hash_function(name1), name2);
            remove_friendship( hash_function(name2), name1);
            break;
        case 'L': //Print out the persons Friends
            print_friendships( hash_function(name1));
            break;
        case 'Q': //Check on friendship
            check_friendship( hash_function(name1), name2);
            break;
        case 'X': //Exit the program **** COMPLETED
            exit(1);
            break;
        default:
            cout<<"Error occured based on your command please try again"<<endl;
            break;
    }
}
int hash_function(string string){
    //going to use the ASCI value of the name with different weights per array position to hash the names
    int ascii_key = 0;
    int ascii_total = 0;
    // cout<< string.length()<< endl;
    //cout<< string<< endl;
    for( int i = 0; i < string.length()-1; i++)
    {
        ascii_total = (int) string[i] * (i*3+1);
        //   cout<< string[i]<< endl;
    }
    ascii_key = ascii_total % SIZE;
    //deals with colisions through open hashing
    /*
     while(hashArray[ascii_key] != NULL || hashArray[ascii_key]-> key != ascii_key) { //strcmp(hashArray[ascii_key]->name.c_str(), string.c_str())
     //hashArray[ascii_key] != NULL ||
     ascii_key++;
     }
     */
    // ****** decide size of the hash table and then finished hashing function. Usually hash time is gonna be half full
    cout<< ascii_key<<endl;
    return ascii_key;
}
void insert_into_hashtable( int ascii_key, string name)
{
    //get the hash key
    user *item =  new user;
    item->name= name;
    item->key = ascii_key;
    item->FriendList = NULL;
    //cout<< ascii_key<<endl;
    //store the user in the table
    hashArray[ascii_key] = item;
    delete(item);
}
void add_friendship( int ascii_key, string name )
{
    //gonna have to check for valid input on users
    list* add  = new friend_list;
    list** temp = &hashArray[ascii_key]->FriendList;
    add->name =  name;
    add->next = NULL;
    if( temp == NULL )
     {
     //cout<<hashArray[ascii_key]->FriendList<<endl;
     *temp = add;
     }
     else
    {
        add->next = *temp;
        *temp = add;
    }
    print_friendships(ascii_key);
}
void print_friendships( int ascii_key)
{
    friend_list* temp  = hashArray[ascii_key]->FriendList;
    while( temp != NULL )
    {
        cout<<temp->name<<endl;
        if( temp->next == NULL)
        {
            return;
        }
        temp = temp->next;
    }
}
Nick b
  • 1
  • 1
  • 1
    I'm pretty sure I don't need to read all those `printf` statements to understand your linked list problem, and I'm absolutely certain I'm not going to try. Please post a [_minimal_ complete and verifiable example](https://stackoverflow.com/help/mcve) instead of just pasting your whole program. – Useless Mar 14 '19 at 16:41
  • does that edit help? – Nick b Mar 14 '19 at 16:49
  • Suggestion: consider separating the list, hash table, and friend logic into their own classes. Right now you've coupled your way into unnecessarily high complexity and in order to debug one aspect of the program, you have to debug all three. This violates encapsulation and low coupling, two of the key principles of Object-Oriented programming. – user4581301 Mar 14 '19 at 17:00
  • Unrelated: If you add an extra layer of indirection, change `list* temp = hashArray[ascii_key]->FriendList;` to `list** temp = &hashArray[ascii_key]->FriendList;`, you can eliminate having to look up `hashArray[ascii_key]` again. `add->next = hashArray[ascii_key]->FriendList;` becomes `add->next = *temp;` and `hashArray[ascii_key]->FriendList = add;` becomes `*temp = add;` – user4581301 Mar 14 '19 at 17:06
  • I don't see your reported error in the given code. You have removed too much. When provicing a [mcve], don't forget Complete. The real goal of MCVE is to get you to hack your code down to a simpler program that is the bug, the whole bug, and nothing but the bug. You almost never have to go all the way to a true MCVE because as the amount of code involved is reduced, the bug has less room to hide and you find and fix it yourself. This is where separating the responsibilities comes in handy: it's easier to remove the stuff you don't need in order to properly investigate the problem. – user4581301 Mar 14 '19 at 17:12
  • Give me one second ill edit the post with everything needed – Nick b Mar 14 '19 at 17:16
  • I've looked at the code in your original post and I'm afraid you have been learning C-style programming, not C++. I recommend supplementing your library with [some better references](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – user4581301 Mar 14 '19 at 17:16
  • I have most of my background in C-style progarmming. Bet they wanted use to use C++ for this- in school – Nick b Mar 14 '19 at 17:20
  • That explains the look. When you get into C++ further you'll find that while the syntax looks the same and C-thinking works in C++, C++ has many ideological differences with C that makes the C-style solution a second-class citizen. Years later I'm still finding and throwing out code I wrote in my "Oh sure, I know C++!" period. – user4581301 Mar 14 '19 at 18:48

1 Answers1

1
void insert_into_hashtable( int ascii_key, string name)
{
    //get the hash key
    user *item =  new user;
    item->name= name;
    item->key = ascii_key;
    item->FriendList = NULL;

    //store the user in the table
    hashArray[ascii_key] = item;
    delete(item);
}

Why are you deleting the item?

Storing a pointer in the array just stores the pointer. It doesn't make a copy of the object pointed to, or somehow protect it against explicit deletion.

Having deleted the object pointed to, dereferencing the pointer is Undefined Behaviour.

Your bug may happen because the next allocated item reuses the same memory (you explicitly said it was free to, by using delete), but the implementation could legally have turned your computer into a potato, so you got off lightly.

You can confirm - and maybe find other similar problems, I'm still not going to wade through all the extraneous I/O code when you could just have programmed a fixed list of calls - by running with valgrind or an address sanitizer.

What you should actually do in an ideal world, is to stop using low-level raw pointers and manual (de)allocation entirely, and instead use smart pointers and idiomatic C++.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • Clearly its been two years too long since Ive programmed heavy. Appreciate your help! I'll be spending time some time relearning pointers and acesssing memory again. Thank you – Nick b Mar 14 '19 at 22:21