1

I'm trying to call a function hfun using a pointer to the function that is held inside a struct.

These are the type definitions:

typedef struct Table* TableP;
typedef struct Object* ObjectP;
typedef int(*HashFcn)(const void *key, size_t tableSize);
typedef struct Object {
    void *key;
    ObjectLink *top;
} Object;

typedef struct Table{
    ObjectLink *linkedObjects;
    size_t size, originalSize;
    HashFcn hfun;
    PrintFcn pfun;
    ComparisonFcn fcomp;
} Table;

And here I'm trying to make the call but get an error that I'm trying to access a place out of memory:

Boolean InsertObject(TableP table, ObjectP object)
{

    int i = (*table->hfun)(object->key, table->size);
    if (table->linkedObjects[i].key == NULL)
    {
        table->linkedObjects[i].key = object;
    } else
    {
        table->linkedObjects[i].next->key = object;
    }

    return TRUE;
}

Using the Eclipse debugger I can tell that in the point of the call the values of the variables are:

object->key type void* value 0x804c018
table->size type size_t value 1

I guess this isn't the way to call a pointer to a function. What is wrong here?

EDIT:

in the debug i can also see: *table->hfun type int(const void *,size_t) table->hfun type HashFcn value 0x11

Tom
  • 9,275
  • 25
  • 89
  • 147
  • Post a compilable example that shows the problem. For example, you don't show how the `hfun` member is initialized - the problem might simply be that it's not. – Michael Burr Dec 25 '12 at 10:20
  • offhand, where is `linkedObjects` ever allocated? You're `InsertObject`certainly things there is space in that array, but without more code, one can only guess whether it references valid data. – WhozCraig Dec 25 '12 at 10:52

1 Answers1

7

You're not calling it the right way.

You can access a function pointer just like any other function.

table->hfun(object->key, table->size)

[Edit] Right, make sure you also assign the hfun properly:

int myFunc(const void* key, size_t tableSize) { }

table->hfun = &myFunc;
Tom van der Woerdt
  • 29,532
  • 7
  • 72
  • 105
  • again i'm getting a 'No source available for "0x11"' – Tom Dec 25 '12 at 10:11
  • 3
    However, there is nothing wrong with using `(*table->hfun)(object->key, table->size)`, so this isn't likely to be the solution to the problem. – Greg Hewgill Dec 25 '12 at 10:11
  • Updated my answer with some additional info about function pointers. – Tom van der Woerdt Dec 25 '12 at 10:17
  • @Tom: Greg's point is that `table->hfun(object->key, table->size)` is exactly equivalent to `(*table->hfun)(object->key, table->size)` – Michael Burr Dec 25 '12 at 10:18
  • @TomvanderWoerdt when i try to make that last assignment i get: assignment from incompatible pointer type – Tom Dec 25 '12 at 10:22
  • @Tom That makes me wonder how you're currently assigning the function pointer. As far as I know, `table->hfun = &function;` is the only correct way to do it, and if that fails for you, that's probably the reason this isn't working. – Tom van der Woerdt Dec 25 '12 at 10:24
  • @TomvanderWoerdt that error disappeared but i'm still getting an error. I edited what i can see from the debugger if that's any help – Tom Dec 25 '12 at 10:32
  • @Tom A value of `0x11` seems invalid. Can you confirm that this is a pointer to `0x00000011`? `printf("%p\n", table->hfun)` should confirm this. If this does in fact spit out 0x00000011, you're not assigning the function pointer properly. – Tom van der Woerdt Dec 25 '12 at 10:34
  • @TomvanderWoerdt it gets corrupted somewhere else in the code. i can confirm it prints the right address after the assignment but later something messes with it. either way thanks! – Tom Dec 25 '12 at 10:49
  • `table->hfun = function;` is perfectly valid also (not that it matters; the amp is optional). While he's at it, print the address of the function he *thinks* is being assigned as well, both after the assignment *and* where things appear to blow up. It is possible somewhere in the code depths the structure is getting trounced as well. Hard to say without full code. – WhozCraig Dec 25 '12 at 10:50
  • @WhozCraig Assigning without taking the reference will implicitly typecast it, yes. Valid code, but (in my opinion) not the correct way to do it. – Tom van der Woerdt Dec 25 '12 at 10:55
  • I can relate to that. You're a rare one, though. For example [this question](http://stackoverflow.com/questions/1952175/how-to-call-the-function-using-function-pointer) dealing strictly with how to setup and use a function pointer had a decent input set from a pretty healthy rep-field, and only a single one of them used `&` prefacing their functions. Still, the standard says `&` is supported, while being utterly silent on *not* using it (that I can see, anyway), so maybe I should start too. Thanks for stoking the grey matter. Have a good holiday! – WhozCraig Dec 25 '12 at 11:54
  • @WhozCraig As far as I know that's because C favors the unpopular format of `void myFunction(void myCallback(void*)) {}`, instead of the more popular format of `void myFunction(void (*myCallback)(void *)) {}`. While they do exactly the same, only the second one makes it obvious that it's a pointer. That said, `myCallback(0)` is more popular than the `(*myCallback)(0)` alternative. Merry Christmas! – Tom van der Woerdt Dec 25 '12 at 12:38