Thread: How to pass multiple user arguments to a callback function?

  1. #1
    Registered User
    Join Date
    Jul 2020
    Posts
    46

    How to pass multiple user arguments to a callback function?

    Hello,

    My question specifically relates to: pcap_loop
    and the uchar pointer which is used to pass the user argument.

    But I think my question relates more to my understanding (or lack of) C pointers.

    The problem that I have is that I want to pass two user arguments and I can't see how to accomplish that.

    The call that I'm making at present (which works), only passes one user argument
    Code:
    pcap_loop(handle , -1 , process_packet , (u_char*)activity_list);
    Where
    Code:
    activity_list
    is a structure (linked list) which I populate with the info that I wish to capture in the
    Code:
    process_packet
    function.

    However, I'd like to be able to pass another structure, which contains info that I can use to customise the behaviour of the process_packet function; and this structure would be completely different to the activity_list structure.

    After some suggestions or suggested readings.

    From my reading of the man page I think this is assumed knowledge, which is why it isn't covered in detail.

    Cheers
    VW

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You get to define the data type you pass in as the user argument to pcap_loop, and thus what gets passed to process_packet. You can just define a struct that contains activity list and whatever else you need. Something like:

    Code:
    struct pcap_user_t {
      activitylist_t activitylist;
      process_packet_options_t process_packet_options;
    };
    pcap_user_t pcap_user_data;
    ...
    pcap_loop(handle, -1, process_packet, (u_char *) &pcap_user_data);
    
    void process_packet(u_char *user_data, const struct pcap_pkthdr *pkthdr, const u_char *packet) {
      pcap_user_t *ud = (pcap_user_t *) user_data;
      // do stuff with ud
    }

  3. #3
    Registered User
    Join Date
    Jul 2020
    Posts
    46
    That is actually pretty straightforward now that you have provided the explanation.

    That's perfect, and that also explains why the man page didn't go into greater detail (although perhaps they should have to cater for newbies).

    Pity the forum doesn't have a 'like' button that I could have clicked on.

    Thanks!

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    491
    When you are setting up a function pointer, you should always pass back a void * supplied by caller. qsort() doesn't do this, which doesn't matter much as the function pointer is usually a trivial comparison function, but as soon as you start to do something a bit more complicated, you will appreciate the extra flexibility.

    If you don't need the user-supplied data, just pass null. If you do need the data, set it up as a structure, then you can have as many user-supplied arguments as you want.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  5. #5
    Registered User
    Join Date
    Jul 2020
    Posts
    46
    Hello,

    Well it seems that I spoke too soon, when I said
    that is actually pretty straightforward
    Because while conceptually it seemed straightforward at the time, some of my existing code is now broken when I try and use a nested structure to pass multiple arguments within a single structure.

    Here is an example
    Code:
    #include <stdio.h>
    #include <pthread.h>
    
    // new_activity list
    struct new_activity_record
    {
        char        c_ip_address[16];
        int         i_local_port;
    };
    typedef struct new_activity_record new_activity_record_t;
    
    
    struct node_new_activity
    {
      new_activity_record_t           new_activity_record;
      struct    node_new_activity    *next;
      struct    node_new_activity    *prev;
    };
    typedef struct node_new_activity node_new_activity_t;
    
    
    struct new_activity_list
    {
      pthread_mutex_t         mutex;
      node_new_activity_t    *head;
      node_new_activity_t    *tail;
    };
    typedef struct new_activity_list new_activity_list_t;
    
    
    struct process_packet_options_record
    {
      char      c_local_subnet[12];
      int       i_subnet_mask;
    };
    typedef struct process_packet_options_record process_packet_options_record_t;
    
    
    struct process_packet_options_list
    {
        struct process_packet_options_record     process_packet_options_record;
        struct process_packet_options_list      *prev;
        struct process_packet_options_list      *next;
    };
    typedef struct process_packet_options_list process_packet_options_list_t;
    
    
    struct pcap_user_data
    {
        struct new_activity_list_t              *new_activity_list;
        struct process_packet_options_list_t    *process_packet_options_list;
    };
    typedef struct pcap_user_data pcap_user_data_t;
    
    
    // declare functions
    void set_pcap_user_data(pcap_user_data_t *arg);
    
    
    int main()
    {
    //  Initialise pcap_user_data
        pcap_user_data_t pcap_user_data;
        set_pcap_user_data(&pcap_user_data);
    
        return 0;
    } // main
    
    
    void set_pcap_user_data(pcap_user_data_t *arg)
    {
    //  Initialise New_Activity_List
        pcap_user_data_t *pcap_user_data = arg;
        pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
    
        return;
    } // set_pcap_user_data
    The error is with this statement
    Code:
    pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
    The error is
    Code:
    |73|error: dereferencing pointer to incomplete type|
    Previously when I just had the new_activity_list structure standalone, I was using
    Code:
    pthread_mutex_lock(&new_activity_list->mutex);
    which worked fine.

    Thanks
    VW

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,543
    > pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
    I figure it should be
    pthread_mutex_init(&pcap_user_data->new_activity_list.mutex,NULL);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jul 2020
    Posts
    46
    Hello Salem,

    Thanks for responding

    Code:
    pthread_mutex_init(&pcap_user_data->new_activity_list.mutex,NULL);
    Code:
    73|error: request for member ‘mutex’ in something not a structure or union|
    VW

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,543
    Code:
    struct pcap_user_data
    {
        new_activity_list_t              *new_activity_list;
        process_packet_options_list_t    *process_packet_options_list;
    };
    typedef struct pcap_user_data pcap_user_data_t;
    Remove the struct from things you've already typedef'ed.

    And go back to ->mutex in the call.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Jul 2020
    Posts
    46
    Have this error

    Code:
    /main.c|125|error: incompatible types when assigning to type ‘process_packet_options_record_t’ from type ‘void *’|
    Which I don't understand what the compiler is trying to tell me

    With this statement;
    Code:
    node->process_packet_options_record = malloc(sizeof(process_packet_options_record_t) * 1);
    Full code
    Code:
    #include <stdio.h>
    #include <pthread.h>
    
    
    // new_activity list
    struct new_activity_record
    {
        char        c_ip_address[16];
        int         i_local_port;
    };
    typedef struct new_activity_record new_activity_record_t;
    
    
    struct node_new_activity
    {
      new_activity_record_t           new_activity_record;
      struct    node_new_activity    *next;
      struct    node_new_activity    *prev;
    };
    typedef struct node_new_activity node_new_activity_t;
    
    
    struct new_activity_list
    {
        pthread_mutex_t         mutex;
        node_new_activity_t    *head;
        node_new_activity_t    *tail;
    };
    typedef struct new_activity_list new_activity_list_t;
    
    
    struct process_packet_options_record
    {
        char      c_local_subnet[12];
        int       i_subnet_mask;
    };
    typedef struct process_packet_options_record process_packet_options_record_t;
    
    
    struct process_packet_options_list
    {
        process_packet_options_record_t  process_packet_options_record;
        struct process_packet_options_list      *prev;
        struct process_packet_options_list      *next;
    };
    typedef struct process_packet_options_list process_packet_options_list_t;
    
    
    struct pcap_user_data
    {
        new_activity_list_t              *new_activity_list;
        process_packet_options_list_t    *process_packet_options_list;
    };
    typedef struct pcap_user_data pcap_user_data_t;
    
    
    // declare functions
    void set_pcap_user_data(pcap_user_data_t *pcap_user_data);
    process_packet_options_list_t *add_at_process_packet_options_list(int pos, process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record);
    process_packet_options_list_t *add_beg_process_packet_options_list(process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record);
    void dump_fwd_process_packet_options_list(pcap_user_data_t *pcap_user_data);
    
    
    int main()
    {
    //  Initialise pcap_user_data
        pcap_user_data_t *pcap_user_data = malloc(sizeof(pcap_user_data_t) * 1);
        if (pcap_user_data == NULL)
        {
            printf("Malloc failed in: Initialise pcap_user_data\n");
            getchar();
        }
    
        pcap_user_data = NULL;
        set_pcap_user_data(&pcap_user_data);
    
        return 0;
    } // main
    
    
    void set_pcap_user_data(pcap_user_data_t *pcap_user_data)
    {
    //  Initialise New_Activity_List
        pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
        pcap_user_data->new_activity_list->head = pcap_user_data->new_activity_list->tail = NULL;
    
    //  Initialise Process_Packet_Options_List
        process_packet_options_list_t *process_packet_options_list = malloc(sizeof(process_packet_options_list_t) * 1);
        if (process_packet_options_list == NULL)
        {
            printf("Malloc failed in: process_packet_options_list\n");
            getchar();
        }
    
        pcap_user_data->process_packet_options_list = NULL;
    
        // Initialise record
        process_packet_options_record_t *process_packet_options_record = malloc(sizeof(process_packet_options_record_t) * 1);
        if (process_packet_options_record == NULL)
        {
            printf("Malloc failed in: process_packet_options_record\n");
            getchar();
        }
    
        // Create process_packet_options_record
        strcpy(process_packet_options_record->c_local_subnet,"192.168.200");
        process_packet_options_record->i_subnet_mask = 24;
    
        // Add process_packet_options_record to process_packet_options_list
        pcap_user_data->process_packet_options_list = add_beg_process_packet_options_list(pcap_user_data->process_packet_options_list, process_packet_options_record);
    
        return;
    
    } // set_pcap_user_data
    
    
    process_packet_options_list_t *add_at_process_packet_options_list(int pos, process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record)
    {
        process_packet_options_list_t *node = malloc(sizeof(process_packet_options_list_t) * 1);
        if (node == NULL)
        {
            printf("Malloc failed in node: add_at_process_packet_options_list\n");
            getchar();
        }
    
        node->process_packet_options_record = malloc(sizeof(process_packet_options_record_t) * 1);
        if (node->process_packet_options_record == NULL)
        {
            printf("Malloc failed in: add_at_process_packet_options_list: node->process_packet_options_record\n");
            getchar();
        }
    
        strcpy(node->process_packet_options_record->c_local_subnet,process_packet_options_record->c_local_subnet);
        node->process_packet_options_record->i_subnet_mask = process_packet_options_record->i_subnet_mask;
        node->prev = NULL;
        node->next = NULL;
    
        // handle case where linked_list is empty
        if (process_packet_options_list == NULL)
        {
            process_packet_options_list = node;
            return process_packet_options_list;
        }
    
        int idx = 0;
    
        process_packet_options_list_t *prev = NULL;
        process_packet_options_list_t *cur  = process_packet_options_list;
    
        // walk through linked_list until pos or end is reached
        while (cur != NULL && idx != pos)
        {
            ++idx;
            prev = cur;
            cur = cur->next;
        }
    
        // insertion point reached
    
        // beginning, includes linked_list update
        if (idx == 0)
        {
            process_packet_options_list = node;
            node->next = cur;
            cur->prev = node;
            return process_packet_options_list;
        }
    
        // end
        if (cur == NULL)
        {
            prev->next = node;
            node->prev = prev;
            return process_packet_options_list;
        }
    
        // middle
        prev->next = node;
        node->prev = prev;
        node->next = cur;
        cur->prev = node;
        return process_packet_options_list;
    
    } // *add_at_process_packet_options_list
    
    
    process_packet_options_list_t *add_beg_process_packet_options_list(process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record)
    {
        process_packet_options_list = add_at_process_packet_options_list(0, process_packet_options_list, process_packet_options_record);
        return process_packet_options_list;
    
    }  // *add_beg_process_packet_options_list
    
    
    void dump_fwd_process_packet_options_list(pcap_user_data_t *pcap_user_data)
    {
        printf("Process Packet Options:\n");
        printf("-----------------------\n");
    
        process_packet_options_list_t linked_list;
        linked_list = pcap_user_data->process_packet_options_list
    
        while (linked_list != NULL)
        {
            printf("Subnet:      %c\n", linked_list->process_packet_options_record->c_local_subnet);
            printf("Subnet mask: %d\n", linked_list->process_packet_options_record->i_subnet_mask);
            printf("\n");
            linked_list = linked_list->next;
        }
    
        return;
    
    } // dump_fwd_process_packet_options_list

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,543
    It isn't a pointer.
    > process_packet_options_record_t process_packet_options_record;
    So there is nothing to malloc.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Jul 2020
    Posts
    46
    Thanks Salem for your last post. It's a pity the forum doesn't have a "like" button so that people who are assisted by responses can acknowledge those useful responses without having to add a separate post (or not acknowledging them at all).

    BTW every time I copy & paste code into the message preview, for every space in my code I get two spaces when I copy & paste. I have tried using notepad rather than copying directly from the IDE. But that made no difference. Has anybody else encountered this behaviour? And if so, is there a workaround?

    I now have a working version of the code, however there are two warnings which I don't understand - and ideally I would like to.

    The warnings are:
    Code:
    main.c|74|warning: passing argument 1 of ‘set_pcap_user_data’ from incompatible pointer type [enabled by default]|
    Statement:
    Code:
    set_pcap_user_data(&pcap_user_data);
    And
    Code:
    main.c|76|warning: passing argument 1 of ‘dump_fwd_process_packet_options_list’ from incompatible pointer type [enabled by default]|
    Statement:
    Code:
    dump_fwd_process_packet_options_list(&pcap_user_data);
    Full code
    Code:
    #include <stdio.h>
    #include <pthread.h>
    
    // new_activity list
    struct new_activity_record
    {
        char        c_ip_address[16];
        int         i_local_port;
    };
    typedef struct new_activity_record new_activity_record_t;
    
    
    struct node_new_activity
    {
      new_activity_record_t           new_activity_record;
      struct    node_new_activity    *next;
      struct    node_new_activity    *prev;
    };
    typedef struct node_new_activity node_new_activity_t;
    
    
    struct new_activity_list
    {
        pthread_mutex_t         mutex;
        node_new_activity_t    *head;
        node_new_activity_t    *tail;
    };
    typedef struct new_activity_list new_activity_list_t;
    
    
    struct process_packet_options_record
    {
        char      c_local_subnet[12];
        int       i_subnet_mask;
    };
    typedef struct process_packet_options_record process_packet_options_record_t;
    
    
    struct process_packet_options_list
    {
        process_packet_options_record_t         *process_packet_options_record;
        struct process_packet_options_list      *prev;
        struct process_packet_options_list      *next;
    };
    typedef struct process_packet_options_list process_packet_options_list_t;
    
    
    struct pcap_user_data
    {
        new_activity_list_t              *new_activity_list;
        process_packet_options_list_t    *process_packet_options_list;
    };
    typedef struct pcap_user_data pcap_user_data_t;
    
    
    // declare functions
    void set_pcap_user_data(pcap_user_data_t *pcap_user_data);
    process_packet_options_list_t *add_at_process_packet_options_list(int pos, process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record);
    process_packet_options_list_t *add_beg_process_packet_options_list(process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record);
    void dump_fwd_process_packet_options_list(pcap_user_data_t *pcap_user_data);
    
    
    int main()
    {
    //  Initialise pcap_user_data
        pcap_user_data_t *pcap_user_data = malloc(sizeof(pcap_user_data_t) * 1);
        if (pcap_user_data == NULL)
        {
            printf("Malloc failed in: Initialise pcap_user_data\n");
            getchar();
        }
    
        pcap_user_data = NULL;
        set_pcap_user_data(&pcap_user_data);
    
        dump_fwd_process_packet_options_list(&pcap_user_data);
    
        return 0;
    
    } // main
    
    
    void set_pcap_user_data(pcap_user_data_t *pcap_user_data)
    {
    //  Initialise New_Activity_List
        new_activity_list_t *new_activity_list = malloc(sizeof(new_activity_list_t) * 1);
    
        if (new_activity_list == NULL)
        {
            printf("Malloc failed in new_activity_list: set_pcap_user_data\n");
            getchar();
        }
    
        pcap_user_data->new_activity_list = new_activity_list;
        pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
        pcap_user_data->new_activity_list->head = pcap_user_data->new_activity_list->tail = NULL;
    
    //  Initialise Process_Packet_Options_List
        process_packet_options_list_t *process_packet_options_list = malloc(sizeof(process_packet_options_list_t) * 1);
    
        if (process_packet_options_list == NULL)
        {
            printf("Malloc failed in process_packet_options_list: set_pcap_user_data\n");
            getchar();
        }
    
        pcap_user_data->process_packet_options_list = process_packet_options_list;
        pcap_user_data->process_packet_options_list = NULL;
    
        // Initialise record
        process_packet_options_record_t *process_packet_options_record = malloc(sizeof(process_packet_options_record_t) * 1);
        if (process_packet_options_record == NULL)
        {
            printf("Malloc failed in process_packet_options_record: set_pcap_user_data\n");
            getchar();
        }
    
        // Create process_packet_options_record
        strcpy(process_packet_options_record->c_local_subnet,"192.168.200");
        process_packet_options_record->i_subnet_mask = 24;
    
        // Add process_packet_options_record to process_packet_options_list
        pcap_user_data->process_packet_options_list = add_beg_process_packet_options_list(pcap_user_data->process_packet_options_list, process_packet_options_record);
    
        // Create process_packet_options_record
        strcpy(process_packet_options_record->c_local_subnet,"192.168.201");
        process_packet_options_record->i_subnet_mask = 24;
    
        // Add process_packet_options_record to process_packet_options_list
        pcap_user_data->process_packet_options_list = add_beg_process_packet_options_list(pcap_user_data->process_packet_options_list, process_packet_options_record);
    
        return;
    
    } // set_pcap_user_data
    
    
    process_packet_options_list_t *add_at_process_packet_options_list(int pos, process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record)
    {
        process_packet_options_list_t *node = malloc(sizeof(process_packet_options_list_t) * 1);
        if (node == NULL)
        {
            printf("Malloc failed in node: add_at_process_packet_options_list\n");
            getchar();
        }
    
        node->process_packet_options_record = malloc(sizeof(process_packet_options_record_t) * 1);
        if (node->process_packet_options_record == NULL)
        {
            printf("Malloc failed in: add_at_process_packet_options_list: node->process_packet_options_record\n");
            getchar();
        }
    
        strcpy(node->process_packet_options_record->c_local_subnet,process_packet_options_record->c_local_subnet);
        node->process_packet_options_record->i_subnet_mask = process_packet_options_record->i_subnet_mask;
        node->prev = NULL;
        node->next = NULL;
    
        // handle case where linked_list is empty
        if (process_packet_options_list == NULL)
        {
            process_packet_options_list = node;
            return process_packet_options_list;
        }
    
        int idx = 0;
    
        process_packet_options_list_t *prev = NULL;
        process_packet_options_list_t *cur  = process_packet_options_list;
    
        // walk through linked_list until pos or end is reached
        while (cur != NULL && idx != pos)
        {
            ++idx;
            prev = cur;
            cur = cur->next;
        }
    
        // insertion point reached
    
        // beginning, includes linked_list update
        if (idx == 0)
        {
            process_packet_options_list = node;
            node->next = cur;
            cur->prev = node;
            return process_packet_options_list;
        }
    
        // end
        if (cur == NULL)
        {
            prev->next = node;
            node->prev = prev;
            return process_packet_options_list;
        }
    
        // middle
        prev->next = node;
        node->prev = prev;
        node->next = cur;
        cur->prev = node;
        return process_packet_options_list;
    
    } // *add_at_process_packet_options_list
    
    
    process_packet_options_list_t *add_beg_process_packet_options_list(process_packet_options_list_t *process_packet_options_list, process_packet_options_record_t *process_packet_options_record)
    {
        process_packet_options_list = add_at_process_packet_options_list(0, process_packet_options_list, process_packet_options_record);
        return process_packet_options_list;
    
    }  // *add_beg_process_packet_options_list
    
    
    void dump_fwd_process_packet_options_list(pcap_user_data_t *pcap_user_data)
    {
        printf("Process Packet Options:\n");
        printf("-----------------------\n");
    
        process_packet_options_list_t *linked_list;
        linked_list = pcap_user_data->process_packet_options_list;
    
        while (linked_list != NULL)
        {
            printf("Subnet:      %s\n", linked_list->process_packet_options_record->c_local_subnet);
            printf("Subnet mask: %d\n", linked_list->process_packet_options_record->i_subnet_mask);
            printf("\n");
            linked_list = linked_list->next;
        }
    
        return;
    
    } // dump_fwd_process_packet_options_list

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Both errors are due to the same mistake.

    Code:
    void set_pcap_user_data(pcap_user_data_t *pcap_user_data);
    ...
        pcap_user_data_t *pcap_user_data = malloc(sizeof(pcap_user_data_t) * 1);
    ...
        set_pcap_user_data(&pcap_user_data);
    You define set_pcap_user_data as a function that has a single parameter of type pointer to pcap_user_data_t. You then define pcap_user_data as a variable of type pointer to pcap_user_data_t; this is the same type that the function takes. But you pass in to the function &pcap_user_data, which is an address of pointer to pcap_user_data_t, also called a pointer to pointer to pcap_user_data_t. The extra address of or pointer to is important, and means it is no longer the right type for the function.

    There's actually no need to malloc anything here. I would just do
    Code:
    pcap_user_data_t pcap_user_data;
    ...
    set_pcap_user_data(&pcap_user_data);
    In that case, you do need the &, since the variable is just of type pcap_user_data_t, so to get a pointer to pcap_user_data_t, you need to use the address of operator, i.e. &. This avoids the need to malloc.

  13. #13
    Registered User
    Join Date
    Jul 2020
    Posts
    46
    The change that you propose works, but I'm confused as to why.

    Specifically I'm trying to understand why if malloc is not required for the
    Code:
    *pcap_user_data
    structure.

    Why doesn't the same approach also work for the
    Code:
    *new_activity_list
    structure?

    If I replace the following
    Code:
    //  Initialise New_Activity_List    new_activity_list_t *new_activity_list = malloc(sizeof(new_activity_list_t) * 1);
    
        if (new_activity_list == NULL)
        {
            printf("Malloc failed in new_activity_list: set_pcap_user_data\n");
            getchar();
        }
    
        pcap_user_data->new_activity_list = new_activity_list;
        pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
    With
    Code:
        new_activity_list_t *new_activity_list;
    
        pcap_user_data->new_activity_list = new_activity_list;
        pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
    While the second example executes (i.e. no syntax error). I encounter an abend in
    Code:
    pthread_mutex_init(&pcap_user_data->new_activity_list->mutex,NULL);
    This makes sense to me. But what I don't understand is why is the malloc not required for the *pcap_user_data assignment?

    And not only is it not required, but it seems that it is wrong for the reason that you have outlined.

    But then why is malloc required for *new_activity_list assignment?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read/Write function callback in user space for a file
    By rupamksarma in forum C Programming
    Replies: 4
    Last Post: 02-28-2012, 04:08 PM
  2. is it possible to pass arguments to the clone fn function?
    By smoking81 in forum Linux Programming
    Replies: 4
    Last Post: 09-12-2008, 10:27 AM
  3. Correct way to pass arguments to this function
    By eponymous in forum C Programming
    Replies: 6
    Last Post: 03-19-2008, 06:56 AM
  4. Member Function Callback - No User Supplied Args
    By Tonto in forum C++ Programming
    Replies: 3
    Last Post: 01-01-2007, 10:26 PM
  5. how do i pass arguments to a function^^^please help
    By adzza69 in forum C++ Programming
    Replies: 3
    Last Post: 08-26-2004, 06:03 PM

Tags for this Thread