Jump to content

Function Pointers

- - - - -

  • Please log in to reply
4 replies to this topic

#1
breimer273

breimer273

    Newbie

  • Members
  • PipPip
  • 16 posts
Hello,

I need help figuring out how to save a function pointer. I will give you an example:

int (*point_to_func)(const void*) = NULL;


void sample_func(int x, int(*save_me)(const void*)){

    point_to_func = save_me;

}


So if its not clear from the above I want to save a function pointer that is passed into a function. I don't think the above is correct but if anyone has had experience with this it would be very helpful.

Thanks,
Bill

#2
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
I actually don't see anything particularly wrong with your implementation, so long as that by "save", you meant that the program should save it for the duration of the program's execution. If you mean on the hard drive, that's a bit more involved of a task...

If you use function pointers regularly, though, you could typedef it to something easier.
typedef int (*my_func_ptr)(const void*) my_func_ptr
Then you can know just by doing this:

my_func_ptr point_to_func = NULL;


void sample_func(int x, my_func_ptr save_me)

{

    point_to_func = save_me;

}

Wow I changed my sig!

#3
breimer273

breimer273

    Newbie

  • Members
  • PipPip
  • 16 posts
I am not really sure what is going on with this entire program. I keep getting errors that I feel I shouldn't be getting but of course there is always a reason for it. Very frustrating but I am trying to keep my cool. Before with the example that I gave you here was what was happening when I tried to compile:

gcc -c -W -Wall -g -I. libpriqueue/libpriqueue.c -o

libpriqueue/libpriqueue.o -o simulator

libpriqueue/libpriqueue.o: In function 'priqueue_init':

/home/engr/reimer1/cs241/reimer1/mp4/libpriqueue/libpriqueue.c:22:

multiple definition of 'compare_func'

libscheduler/libscheduler.o:/home/engr/reimer1/cs241/reimer1/mp4/libscheduler/libscheduler.c:29:

first defined here

collect2:ld returned 1 exit status

make: *** [simulator] Error 1

No idea what that means because obviously it failed to compile but the compiler I guess couldn't tell me where it failed... Never had that happen before. Now I tried changing it to the way you suggested here is what I get now:

gcc -c -W -Wall -g -I. libpriqueue/libpriqueue.c -o libpriqueue/libpriqueue.o

In file included from libpriqueue/libpriqueue.c:9:

libpriqueue/libpriqueue.h:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘compare_func_ptr’

libpriqueue/libpriqueue.h:18: error: expected declaration specifiers or ‘...’ before ‘compare_func_ptr’

libpriqueue/libpriqueue.c:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘compare_func’

libpriqueue/libpriqueue.c:20: error: expected declaration specifiers or ‘...’ before ‘compare_func_ptr’

libpriqueue/libpriqueue.c: In function ‘priqueue_init’:

libpriqueue/libpriqueue.c:23: error: ‘compare_func’ undeclared (first use in this function)

libpriqueue/libpriqueue.c:23: error: (Each undeclared identifier is reported only once

libpriqueue/libpriqueue.c:23: error: for each function it appears in.)

libpriqueue/libpriqueue.c:23: error: ‘comparer’ undeclared (first use in this function)

libpriqueue/libpriqueue.c: In function ‘priqueue_offer’:

libpriqueue/libpriqueue.c:50: warning: implicit declaration of function ‘compare_func’

make: *** [libpriqueue/libpriqueue.o] Error 1

And for your reference here are the .h and .c files respectively:

/*

 * Machine Problem #4

 * CS 241

 * The University of Illinois

 */


#ifndef LIBPRIQUEUE_H_

#define LIBPRIQUEUE_H_

typedef int (*compare_func_ptr)(const void*, const void *) compare_func_ptr; //<------typedef Function pointer declaration


typedef struct priqueue_t{

	struct priqueue_t * next;

	void *data;


} priqueue_t;



void   priqueue_init     (priqueue_t *q, compare_func_ptr comparer);


int    priqueue_offer    (priqueue_t *q, void *ptr);

void * priqueue_peek     (priqueue_t *q);

void * priqueue_poll     (priqueue_t *q);

void * priqueue_at       (priqueue_t *q, int index);

int    priqueue_remove   (priqueue_t *q, void *ptr);

void * priqueue_remove_at(priqueue_t *q, int index);

int    priqueue_size     (priqueue_t *q);


void   priqueue_destroy  (priqueue_t *q);



#endif /* LIBPQUEUE_H_ */



/*

 * Machine Problem #4

 * CS 241

 * The University of Illinois

 */


#include <stdlib.h>

#include <stdio.h>

#include "libpriqueue.h"


/*

 * You can find the struct priqueue_t in libpriqueue.h.

 */


compare_func_ptr compare_func = NULL;         //<-------------Function pointer initialization

/*

 * priqueue_init()

 * Initializes the priqueue_t data structure.

 */

void priqueue_init(priqueue_t *q, compare_func_ptr comparer)

{

	q = (priqueue_t*)malloc(sizeof(priqueue_t));

	compare_func = comparer;                      //<----------------Function pointer assignment

	q->next = NULL;

	q->data = NULL;

}



/*

 * priqueue_offer()

 * Inserts the specified element into this priority queue.

 *

 * Returns: The zero-based index where ptr is stored in the priority queue,

 * where 0 indicates that ptr was stored at the front of the priority queue.

 */

int priqueue_offer(priqueue_t *q, void *ptr)

{

	priqueue_t * current = q;

	priqueue_t * new_node = (priqueue_t *)malloc(sizeof(priqueue_t));

	priqueue_t * temp = current->next;

	new_node->data = ptr;

	int compare_result;

	int counter = 0;

	if(temp == NULL){

		current->next = new_node;

		return counter;

		}

	counter++;

	while(temp != NULL){

		compare_result = compare_func(temp->data, new_node->data);

		if(compare_result < 0){

			new_node->next = temp;

			current->next = new_node;

			return counter;

		}

		else if(compare_result >= 0){

			counter++;

			current = current->next;

			temp = temp->next;

		}

	}

	//If we get to this point the job must be added to the end of the queue

	temp->next = new_node;

	new_node->next = NULL;

	return counter;

}



/*

 * priqueue_peek()

 * Retrieves, but does not remove, the head of this queue, returning NULL if

 * this queue is empty.

 *

 * Returns: The head of the queue, or NULL if the queue is empty.

 */

void *priqueue_peek(priqueue_t *q)

{

	return q->next;

}



/*

 * priqueue_poll()

 * Retrieves and removes the head of this queue, or NULL if this queue

 * is empty.

 *

 * Returns: The head of this queue, or NULL if this queue is empty.

 */

void *priqueue_poll(priqueue_t *q)

{

	priqueue_t * temp = q->next;

	q->next = temp->next;

	return temp;

}



/*

 * priqueue_at()

 * Returns the element at the specified position in this list, or NULL if

 * the queue does not contain an index'th element.

 *

 * Returns: The index'th element in the queue, or NULL if the queue does

 * not contain in index'th element.

 */

void *priqueue_at(priqueue_t *q, int index)

{

	priqueue_t * temp = q->next;

	int i;

	for(i = index; i > 0; i--){

		temp = temp->next;

	}

	return temp;

}



/*

 * priqueue_remove()

 * Removes all instances of ptr from the queue. This function should not

 * use the comparer function, but check if the data contained in each

 * element of the queue is equal (==) to ptr.

 *

 * Returns: The number of entries removed.

 */

int priqueue_remove(priqueue_t *q, void *ptr)

{

	int counter;

	priqueue_t * temp = q->next;

	priqueue_t * lead_temp = q;

	while(temp != NULL){

		if(temp->data == ptr){

			lead_temp->next = temp->next;

			free(temp);

			temp = lead_temp->next;

			counter++;

		}

		temp = temp->next;

		lead_temp = lead_temp->next;

	}

	return counter;

}



/*

 * priqueue_remove_at()

 * Removes the specified index from the queue, moving later elements up

 * a spot in the queue to fill the gap.

 *

 * Returns: The element removed from the queue, or NULL if the specified

 * index does not exist.

 */

void *priqueue_remove_at(priqueue_t *q, int index)

{

	priqueue_t * temp = q->next;

	priqueue_t * lead_temp;

	while(temp != NULL && index > 0){

		temp = temp->next;

		lead_temp = lead_temp->next;

		index--;

	}

	if(temp != NULL){

		lead_temp->next = temp->next;

	}

	return temp;

}



/*

 * priqueue_size()

 * Returns the number of elements in the queue.

 *

 * Returns: The number of elements in the queue.

 */

int priqueue_size(priqueue_t *q)

{

	int counter = 0;

	priqueue_t * temp = q->next;

	while(temp != NULL){

		temp = temp->next;

		counter++;

	}

	return counter;

}



/*

 * priqueue_destroy()

 * Destroys and frees all the memory associated with q.

 */

void priqueue_destroy(priqueue_t *q)

{

	priqueue_t * temp = q->next;

	while(temp != NULL){

		free(q);

		q = temp;

		temp = temp->next;

	}

	free(q);

}

This assignment was due 24 hours ago so I am probably not going to get any credit for it, because of these stupid compile errors (not even sure if the code works). But now I just want to get it done because it is bugging me.

#4
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
typedef int (*compare_func_ptr)(const void*, const void *) compare_func_ptr;
This is wrong. I know I did it, it was a code snippet and I accidentally added that last my_func_ptr. Don't put that at the end, as I believe that declares a new one of that type. Just omit it.
typedef int (*compare_func_ptr)(const void*, const void *);

Wow I changed my sig!

#5
breimer273

breimer273

    Newbie

  • Members
  • PipPip
  • 16 posts
You're awesome, that did the trick. Now I just have a segfault, yay! But at least it compiles I think I can figure out where the rest of my problems are from here.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users