0

This is a follow up to how to create a function pointer to add a print method, Adding a function pointer within a struct to print. Let's say I've created this as follows:

typedef struct Book {
    char* title;
    unsigned int year;
    void (*print)(struct Book *book);
} Book;

void print(Book *book)
{
    printf("{\n\ttitle: \"%s\",\n\tyear: %d\n}\n", book->title, book->year);
}

int main(int argc, char * argv[])
{

    Book book  = {
        .title="Jaws",
        .year=2000
    };
    print(&book);      // this works
    book.print(&book); // this seg faults

}

What would be the proper way to do the book.print() call?

carl.hiass
  • 1,526
  • 1
  • 6
  • 26
  • When declaring `Book book` (or after declaring it) you also need to initialized `book.print` if you intend to use it. – goodvibration Nov 01 '20 at 20:17
  • @goodvibration -- I see, so adding in the `.print=print` to the struct declration? – carl.hiass Nov 01 '20 at 20:18
  • 1
    I would suggest renaming the attribute `print` in the structure `Book`, in order to avoid (yourself) confusing it with the function named `print`. – goodvibration Nov 01 '20 at 20:18
  • 1
    Yes to your question above, but see my additional comment below it. – goodvibration Nov 01 '20 at 20:19
  • you didn't set `book.print`, that's all. One language feature c _doesn't_ have is binding functions to structures. – erik258 Nov 01 '20 at 20:27
  • The confusion in `.print=print` comes from the fact that it is 100% okay, there is no namespace collision as struct member names and function names occupy different namespaces. (though that does nothing to solve the confusion created by the human brain when looking at it) – David C. Rankin Nov 01 '20 at 20:35

1 Answers1

3

It segfaults because you have not assigned the print pointer. Try this instead:

int main(int argc, char * argv[])
{

    Book book  = {
        .title="Jaws",
        .year=2000,
        .print=print
    };
    print(&book);      // this works
    book.print(&book); // this no longer seg faults
}
Ken Wayne VanderLinde
  • 18,915
  • 3
  • 47
  • 72
  • There is no "book pointer" in the code (unless you mean `&book`, but that one doesn't need to be assigned, as it points to a local `Book` object). – goodvibration Nov 01 '20 at 20:21
  • @Ken -- thanks, that works. What 'type' is a function (or function label?) is it considered a pointer to the memory address where that function starts? – carl.hiass Nov 01 '20 at 20:21
  • @carl.hiass - yes, the function pointer is just the address for the function itself. You match the type to the function declaration as you have done in your struct. (BTW, Jaws was 1975 `:)` – David C. Rankin Nov 01 '20 at 20:27
  • @KenWayneVanderLinde may want to update `// this seg faults` to `// this works now too` `:)` And I would change `int argc, char *argv[]` to `void` to avoid the compiler warnings for unused-variables... (both just nits) – David C. Rankin Nov 01 '20 at 20:36
  • @DavidC.Rankin Copy pasta strikes again! Thanks for pointing it out. I decided to leave the function signature as it is since this is taken directly from the question. – Ken Wayne VanderLinde Nov 02 '20 at 03:21
  • Yep, that's all good. I always kind of chuckle when the answer still has "this segfaults" (I'm guilty myself...) Thanks for to the good answer. – David C. Rankin Nov 02 '20 at 03:39