2

Hi I'm a beginner and I'm trying to work out some pointer to function examples. I can't even compile my code, it shows the following message. I cannot determine why I am getting the compilation errors.

/tmp/cc0qghbo.o: In function `main':
pointer_to_function_inside_structure.c:(.text+0x88): undefined reference to `func_ptr'
collect2: ld returned 1 exit status

here is my code, please tell me what I'm doing wrong

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

struct student_data
{
        char *name;
        int roll_num;
        int marks;
        void (* func_ptr)(struct student_data *ptr);
};

void print_data(struct student_data *ptr);

void print_data(struct student_data *ptr)
{
        printf("\nNAME OF THE STUDENT      %s", ptr -> name);
        printf("\nROLL NUMBER OF STUDENT   %d", ptr -> roll_num);
        printf("\nMARKS OF STUDENT         %d\n", ptr -> marks);
}

int main()
{
        struct student_data *ptr;

        ptr -> name = "ajish";
        ptr -> roll_num = 2;
        ptr -> marks = 50;

        ptr -> func_ptr = &print_data;
        func_ptr(ptr);
}
octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
ajishalfred
  • 277
  • 1
  • 3
  • 7
  • 1
    Your last line `func_ptr(ptr)` is using an undeclared variable `func_ptr`. You happen to have a field member with the same name, perhaps you intended `ptr->func_ptr(ptr)`? – Raymond Chen Nov 07 '11 at 17:32

2 Answers2

5
  1. You're not allocating memory using your pointer.
  2. Since func_ptr is a member of student_data you have to call your function using struct student_data *ptr which should be pointer to the instance of your struct.

Example:

int main()
{
    // allocate memory
    struct student_data *ptr = malloc(sizeof(student_data));

    ptr -> name = "ajish";
    ptr -> roll_num = 2;
    ptr -> marks = 50;

    ptr -> func_ptr = &print_data;

    // change this to:
    ptr->func_ptr(ptr);

   // free memory
   free(ptr);
}
cpx
  • 17,009
  • 20
  • 87
  • 142
  • +0: while this is right, it doesn't address the compiler error. – Adam Maras Nov 07 '11 at 17:36
  • @AdamMaras: I've already suggested the OP to change `func_ptr(ptr);` to `ptr->func_ptr(ptr);` in my example. – cpx Nov 07 '11 at 17:42
  • @cpx I apologize, I did not see the comment in the code example. But you would do well to have mentioned why that line of code was changed in the body text of your answer. – Adam Maras Nov 07 '11 at 17:53
  • please remove the cast of `malloc`'s return value. (Warning: the type `student_data` is not defined, you mean `struct student_data`!) – u0b34a0f6ae Nov 07 '11 at 18:25
  • @kaizer.se: Thanks, I didn't notice that! – cpx Nov 07 '11 at 18:38
  • `malloc(sizeof(struct student_data));` *without* casting the return value. – u0b34a0f6ae Nov 08 '11 at 21:28
  • 1
    @kaizer.se VC++ compiler warns if i remove the cast `warning C4047: 'initializing' : 'struct student_data*' differs in levels of indirection from 'int'` but after looking at this [question](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) I think it is generally not needed. Thanks. – cpx Nov 08 '11 at 21:48
  • 1
    A C++ compiler would warn/flag for that issue. Anyway it's not horriby important. – u0b34a0f6ae Nov 08 '11 at 21:49
2

You need to change the last line before main()'s closing brace from

func_ptr(ptr);

to

ptr -> func_ptr(ptr);

After that change, the program compiled and ran for me. I compiled with gcc 4.5.0.

You should also either

  1. Allocate space for ptr on the heap

    struct student_data *ptr = malloc(sizeof(struct student_data));
    

    Don't forget to free it at the end of your program:

    free(ptr);
    

    Or

  2. Declare ptr on the stack.

    struct student_data ptr;
    

    This will require you to change all your -> operators on ptr to . operators.

Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77