pthread, passing 2d arry

I am new to thread programming. I need help casting an array so that it can be passed to a thread as a void pointer. In the thread I need to de-cast my array to have access to any member of the array. Here is what I want to do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main ()
{
.
.
int i;
pthread_t thread1;

fc = new FatCase *[100]; //This array should be passed to the thread
  for (i = 0; i < 100; i++)
    fc[i] = new FatCase[100];
.
.
pthread_create( &thread1, NULL, fefat, &fc[0][0]);
.
.
}

"fefat" is the function which works on the array "fc":
1
2
3
4
5
6
7
8
9
int fefat(void *pParam)
{
.
.
.
FatCase **fc = (FatCase **) pParam; //this is the try to de-cast 
.
.
}

Well, I get an error message:
Error conversion from FatCase** to ...

I really havn't undestood how this could be done. Therefore any help is very much appreciated.

Regards
Peter
Last edited on
First, as a rule, it's not as helpful to write
Error conversion from FatCase** to ...
when you could easily publishe the full error and indicate what line number it occurred on.

Second, if you use variables in presenting a problem, it's often helpful to show the type. It saves a lot of guessing on the reader's part.

Have you thought about the layout of your 2D array? It's not really a 2D array at all it's an array of array pointers, so the memory layout isn't contiguous. It's a similar layout to argv that's passed into main. So fc isn't the same as &fc[0][0].

Having said that, it should be clear that you need to pass fc to pthread_create.

There's also the general point that you shouldn't be using thread functions, but thread classes. As you've discovered, a thread often needs "stuff" to work with. Without careful management, the thread's stuff get's mixed with the other stuff and it gets confusin very quickly. If you use a thread class, you contain the stuff lying around and it get's declared where it's needed. In your case, the stuff is your 2D array. But this has no direct bearing on the problem at hand.
Use this
pthread_create( &thread1, NULL, fefat, &fc[0][0]);
or this
pthread_create( &thread1, NULL, fefat, fc);

While casting
FatCase *fc[100] = (FatCase *[]) pParam;
then use fc[0], fc[1] like that.

I hope this helps you.
Hello kbw,
thanks for the advice. I will post the complete error message in the future, sorry. Here is also the type of fc:
fc is defined in the main function like this:
 
FatCase **fc;

The class FatCase is definded in the header file like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class FatCase {
public:
  char fn_event[201];
  char fn_fem[201];
  int gate;
  int repeats;
  int tag;
  double lc_factor;
  double sf;
  double betha;
  double uts;
  int r_bins;
  int m_bins;
  double minr;
  double maxr;
  double minm;
  double maxm;
  double dam;
  int dam_node;
  int lcno;
  int node_anz;
  int l;
  int stressMethod;
  int msc_flag;
  int rfm_lines;
  int max_rfm_lines;
  int hof;
  int snode[10];
  int enode[10];
  double stress_scale_factor;
  int fcas;
};

as far as I understand my problem I am not able to send the start address of my array as a void pointer via pthread_create to my thread function in a way, that I later can cast it back to my array in the thread function.

Hello richardforc,
thanks for your help so far. After I implemented the changes you suggested, I get now again an error:

fefat.c: In function ' int fefat(void*)':
fefat.c:20:34: error: ISO C++ forbids casting to an array type 'FatCase* []'
fefat.c:20:34: error: array must be initialized with a brace-enclosed initializer

I really hope you can help me further on this subject.
Regrads
Peter
OK calculix. You can go with normal double pointer casting.

 
FatCase **fc = (FatCase **) pParam;


Then go with fc[0], fc[1]... fc[99]. Each fc[i] have 100 FatCase object within it. Remember that while moving further. Thanks.
Happy coding!!!
Last edited on
You ought to be able to call:
 
pthread_create( &thread1, NULL, fefat, reinterpret_cast<void*>(fc));

Then on the receiving side do:
1
2
3
4
5
6
7
int fefat(void *pParam)
{
    if (FatCase** fc = reinterpret_cast<FatCase**>(pParam))
    {
        //...
    }
}


That should sort out your parameter passing issue.

Thanks a lot! I am getting closer. My thread function (fefat.c) does compile now with both suggested solutions. Unfortunatly I get now an error in the main function:

fgc.c:136:76: error: invalid conversion from 'int (*)(void*)' to 'void* (*)(void*)'
fgc.c:136:76: error: initializing argument 3 of 'int pthread_create(pthread_t* pthread_attr_t_* const*, void* (*)(void), void*)'

Why is fc of type 'int (*)(void*)' and how do I cast it to type 'void* (*)(void*)' in a proper way in function main?

Please help.

Regards
Peter
Last edited on
Your thread function should be:
 
void* fefat(void*)
rather than return an int.
Thanks a lot for the great help!!
Now my code got compiled properly. Still I have to do some bugfixing to do, but this is not thread dependent.
:-)
Regards
Peter
Last edited on
Topic archived. No new replies allowed.