I'm trying to write simplest generic linked list in ansi c (c89).
Here's code:
#include <stdio.h> #include <stdlib.h> #include <time.h> struct node { struct node *previous; struct node *next; void *value; }; struct node* allocate_node(void); void free_node(struct node *freeable_node); void init_node(struct node *initializable_node); void print_node(struct node *printable_node); struct node* allocate_node(void) { struct node *allocatable_node = (struct node*) calloc(1, sizeof(struct node)); allocatable_node -> previous = NULL; allocatable_node -> next = NULL; return allocatable_node; } void free_node(struct node *freeable_node) { free(freeable_node -> previous); free(freeable_node -> next); free(freeable_node -> value); free(freeable_node); } void init_node(struct node *initializable_node) { int *initializable_value = (int*) (initializable_node -> value); initializable_value = calloc(1, sizeof(int*)); *initializable_value = rand() % 100; } void print_node(struct node *printable_node) { printf("%d\n", *((int*) (printable_node -> value))); } int main(void) { struct node *demo_list = NULL; srand((unsigned int) time(NULL)); demo_list = allocate_node(); init_node(demo_list); print_node(demo_list); free(demo_list); return 0; } Via clang it compiles successfully, but after running prints segfault.
And valgrind output:
$ valgrind ./build/app ==23061== Memcheck, a memory error detector ==23061== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==23061== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==23061== Command: ./build/app ==23061== ==23061== Invalid read of size 4 ==23061== at 0x4007AE: print_node (app.c:56) ==23061== by 0x400813: main (app.c:67) ==23061== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==23061== ==23061== ==23061== Process terminating with default action of signal 11 (SIGSEGV) ==23061== Access not within mapped region at address 0x0 ==23061== at 0x4007AE: print_node (app.c:56) ==23061== by 0x400813: main (app.c:67) ==23061== If you believe this happened as a result of a stack ==23061== overflow in your program's main thread (unlikely but ==23061== possible), you can try to increase the size of the ==23061== main thread stack using the --main-stacksize= flag. ==23061== The main thread stack size used in this run was 8388608. ==23061== ==23061== HEAP SUMMARY: ==23061== in use at exit: 32 bytes in 2 blocks ==23061== total heap usage: 2 allocs, 0 frees, 32 bytes allocated ==23061== ==23061== LEAK SUMMARY: ==23061== definitely lost: 8 bytes in 1 blocks ==23061== indirectly lost: 0 bytes in 0 blocks ==23061== possibly lost: 0 bytes in 0 blocks ==23061== still reachable: 24 bytes in 1 blocks ==23061== suppressed: 0 bytes in 0 blocks ==23061== Rerun with --leak-check=full to see details of leaked memory ==23061== ==23061== For counts of detected and suppressed errors, rerun with: -v ==23061== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Segmentation fault Any ideas how to fix it?
void *value;can handle pointers to objects, but nor certainly pointers to functions. For that, use aunionofvoid*andint (*)().