0

Say I have a array of array of struct pollfds

 int Pipes = 2;
 struct pollfd pollFD[nArguments][nPipes];

nArguments is a variable that is determined inside the main, I can't know it's value before run time and I need to place this array of pollfd inside a struct to pass it as an argument to a thread.

How can I convert it to

struct pollfd **pollFDConverted;

Edit: I found the solution at this link:Malloc a 2D array in C

JavaDumbell
  • 215
  • 2
  • 11
  • 1
    Wrap it in a structure `struct Mypollfd { struct pollfd **pollFDConverted; size_t nArguments; size_t nPipes;}` and then pass `struct Mypollfd*` to the thread? – Zoso Apr 16 '21 at 17:50

2 Answers2

2

One can do something like this:

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

struct pollFDWrapper {
    struct pollfd ** arr;
    size_t nRows;
    size_t nCols;
};

static void* thread_handler(void *arg)
{
    struct pollFDWrapper * wrapper = arg;
    for(size_t i = 0; i < wrapper->nRows; ++i)
        for(size_t j = 0; j < wrapper->nCols; ++j) {
            (void) wrapper->arr[i][j];
        }
            
    return NULL;
}

int main(void)
{
    struct pollFDWrapper * arg = malloc(sizeof *arg);
    //Dimensions can be obtained as required, just for demonstration
    arg->nRows = 3;
    arg->nCols = 5;
    arg->arr = calloc(sizeof arg->arr[0], arg->nRows); //create array of pointers
    for(size_t i = 0; i < arg->nRows; ++i) {
        arg->arr[i] = calloc(sizeof arg->arr[i][0], arg->nCols); //crate array
    }

    pthread_t thread;

    if (pthread_create(&thread, NULL, thread_handler, arg) != 0)
    {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }
    if (pthread_join(thread, NULL) != 0)
    {
        perror("pthread_join");
        exit(EXIT_FAILURE);
    }
    for(size_t i = 0; i < arg->nRows; ++i) {
        free(arg->arr[i]); //free array
    }
    free(arg->arr); //free ptr to array
    free(arg); //free the encapsualting struct
    return 0;
}

struct pollFDWrapper encapsulates the information needed for manipulating the struct pollfd ** arr, including the dimensions of the 2-D array and can be passed around, even to a thread, just like a regular pointer.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Zoso
  • 3,273
  • 1
  • 16
  • 27
1

How can I convert it to

struct pollfd **pollFDConverted;

You don't want to do that, the compiler needs to know the number of elements of the last dimension, on the other hand a thread handler uses a pointer to void as parameter and you can pass whatever you want to it (except a pointer to function).

Just convert to the proper type (in this case I'm reading a 2D array of ints via a pointer to an array of n ints, you can adapt this to your struct):

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

enum {rows = 2, cols = 3};

static void *thread_handler(void *arg)
{
    int (*arr)[cols] = arg;

    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < cols; col++)
        {
            printf("%d ", arr[row][col]);
        }
        printf("\n");
    }
    return NULL;
}

int main(void)
{
    int arr[rows][cols] = {{1, 2, 3}, {4, 5, 6}};
    pthread_t thread;

    if (pthread_create(&thread, NULL, thread_handler, arr) != 0)
    {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }
    if (pthread_join(thread, NULL) != 0)
    {
        perror("pthread_join");
        exit(EXIT_FAILURE);
    }
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94