0

I have a struct containing amongst other things a function variable that I would like to assign a function to that is itself visible on the global level, like so:

typedef struct HashMap{
    struct LinkedList** datapointers;
    int key_space;
    int* (*hash_function)(const char*);
}HashMap;
unsigned int hashfunction(const char* input){
    int i=0;
    int hash=0;
    while(input[i]){
        hash=hash+input[i]; 
        i++;
    }
    return hash;
}
//create a new hashmap 
HashMap* create_hashmap(int key_space){
    HashMap *hm = malloc (sizeof(HashMap));
    hm->datapointers = malloc(sizeof(LinkedList)*key_space); //array of linked lists 
    hm->key_space=key_space; 
    for(int i=0;i<key_space;i++){ //initalize to NULL 
        hm->datapointers[i]=NULL;
    }
    hm->hash_function=*hashfunction;
    return hm;
}

now no matter what I do I keep getting invalid pointers or undeclared variables. Is there any way to get this to work right?

Thank you

1
  • what is the definition of LinkedList? Commented Nov 28, 2014 at 12:46

4 Answers 4

1

Your code should read like

hm->hash_function = hashfunction;

but, there is a mismatch.

the function pointer type is int* (*hash_function)(const char*);

but your function signature is

unsigned int hashfunction(const char* input)

IMO, it should be

  1. int* hashfunction(const char* input) [need to modify function definition accordingly]

or

  1. unsigned int (*hash_function)(const char*);
Sign up to request clarification or add additional context in comments.

1 Comment

Ah yes that teaches me not to copy paste other pieces of code for signatures.
1

I got a bunch of warning. Here's the modified code that doesn't give any warning:

typedef struct HashMap{
    struct LinkedList** datapointers;
    int key_space;
    int (*hash_function)(const char*);
}HashMap;
int hashfunction(const char* input){
    int i=0;
    int hash=0;
    while(input[i]){
        hash=hash+input[i]; 
        i++;
    }
    return hash;
}
//create a new hashmap 
HashMap* create_hashmap(int key_space){
    HashMap *hm = malloc (sizeof(HashMap));
    hm->datapointers = malloc(sizeof(LinkedList)*key_space); //array of linked lists 
    hm->key_space=key_space; 
    for(int i=0;i<key_space;i++){ //initalize to NULL 
        hm->datapointers[i]=NULL;
    }
    hm->hash_function=hashfunction;
    return hm;
}

Changes are: 1. The function pointer hash_function doesn't return int * but int.

  1. The hashfunction now returns int instead of unsigned int.

  2. While assigning hashfunction to hash_function, don't dereference it.

Comments

1

You should code

  hm->hash_function = hashfunction;

also, your hashfunction has an incorrect signature. Define it as:

  int hashfunction(const char* input)

without the unsigned, and declare the field:

 int (*hash_function)(const char*);

BTW, you better understand what are closures. You probably should consider adding some client data to every function used indirectly. You could for example add a field void* client_data; inside your struct HashMap. See also this. Read more about callbacks.

At last, I find much more readable to declare with a typedef the signature (used in pointers to function) like here.

1 Comment

that gives a warning assignment from inccompatible pointer type, is it ok to ignore this?
0
The following is the correct code.
However, since the LinkedList is not defined in your posted code, 
it fails to compile.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// where/what is the definition of LinkedList?

// define the HashMap struct
struct HashMap
{
    struct LinkedList** datapointers;
    int key_space;
    unsigned int (*hash_function)(const char*);
};

// prototypes
unsigned int hashfunction(const char*);
struct HashMap* create_hashmap(int);


unsigned int hashfunction(const char* input)
{
    int i=0;
    unsigned int hash=0;

    while(input[i])
    {
        hash += input[i];
        i++;
    } // end while

    return hash;
} // end function: hashfunction


//create a new hashmap
struct HashMap* create_hashmap(int key_space)
{
    // define an instance of the HashMap struct
    struct HashMap *hm = malloc (sizeof(struct HashMap));
    if( NULL == hm )
    { // then malloc failed
        perror( "malloc of HashMap failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    // array of linked lists
    if( NULL == hm->datapointers = malloc(sizeof(LinkedList)*key_space) )
    { // then, malloc failed
        perror( "malloc of HashMap.datapointer failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    // fill in fields of HashMap
    hm->key_space=key_space;
    memset( hm->datapointers, 0x00, sizeof(LinkedList*key_space) );
    hm->hash_function = &hashfunction;

    return hm;
} // end function: create_hashmap

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.