Did you know that ransomware is the most widespread, destructive malware in the world today? It accounts for 39% of all security breaches, with ransomware gangsters projected to make $11.5B in profits from online extortion by 2019.

Hi all,

I'm having the problem in passing the num_thread from my main.c to mcompute.c, in line 39 it prints out 0(instead of 2 from the command line argument). hence, i got an Arithmetic Exception (core dumped) after it.

Can anyone help me in this, my code is a little messy since this is my first time splitting up the code into several files, so i'm kind of weak in passing the arguments.

These are the global var i have in my matmul.h:

int num_thread; // number of threads

int itt_max; // number of itterations to preform

int seed; // seed for srand48() / drand48()

int n; // problenm size

double *a; // pointer to transfromation array, space to be malloced

double *b; // pointer to transfromation vector, space to be malloced

double *err;

I'm having the problem in passing the num_thread from my main.c to mcompute.c, in line 39 it prints out 0(instead of 2 from the command line argument). hence, i got an Arithmetic Exception (core dumped) after it.

Can anyone help me in this, my code is a little messy since this is my first time splitting up the code into several files, so i'm kind of weak in passing the arguments.

These are the global var i have in my matmul.h:

int num_thread; // number of threads

int itt_max; // number of itterations to preform

int seed; // seed for srand48() / drand48()

int n; // problenm size

double *a; // pointer to transfromation array, space to be malloced

double *b; // pointer to transfromation vector, space to be malloced

double *err;

```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include "matmul.h"
void srand48(long int seedval);
double drand48(void);
void* compute(void* thrd)
{
int from, to;
int s = (int)thrd;
int i, j;
double *t; // pointer to solution vector, space to be malloced
double *t1; // pointer to next itteraton of solution vector,
// space to be malloced
double *ttemp; // used to swap t1 and t at each itteration
int itt; // current itteration
double sum; // computes the inner products for A * t
double error; // max | t1[i] - t[i] |
double errori; // | t1[i] - t[i] |
if( (t=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t failed\n");
}
if( (t1=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t1 failed\n");
}
if( (err = (double*) malloc (sizeof (double) * itt_max)) == NULL)
{
fprintf(stderr," ERROR : malloc for err failed\n");
}
printf("Number of threads is: %d \n\n", num_thread);
for(i=0; i< n; i++)
{
t[i] = b[i];
}
if( s < num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread - 1;
}
else if ( s == num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread;
}
for(itt=from; itt<=to; itt++)
{
error=0.0;
for(i=0; i< n; i++)
{
sum = 0.0;
double *a_itt = a + n*i;
for(j=0; j< n; j++)
{
sum += *(a_itt++) * t[j];
}
t1[i] = sum + b[i];
errori = fabs(t1[i]-t[i]);
if(errori > error)
{
error=errori;
}
}
err[itt] = error;
ttemp = t1;
t1 = t;
t = ttemp;
//printf("%5d %14.6e\n", itt, error);
}
pthread_exit(0);
}
int mcompute(int n, int seed, int itt_max, int num_thread, double *a, double *b)
{
srand48((long int)seed);
float resultb[n];
int i, j; // indices into arrays
pthread_t* thread; // pointer to a group of threads
float **resulta = (float**)malloc(sizeof(float*)*n);
for(i=0; i< n; i++)
*(resulta+i) = (float*)malloc(sizeof(float)*n);
for(i=0; i< n; i++)
{
for(j=0; j< n; j++)
{
*(a+n*i+j) = 1.999 * (drand48() - 0.5) / n;
resulta[i][j] = *(a+n*i+j);
}
}
moutput_a(resulta, n);
// Generate vector b
for(i=0; i< n; i++)
{
b[i] = 10.0 * drand48();
resultb[i] = b[i];
}
moutput_b(resultb, n);
thread = (pthread_t*)malloc(num_thread*sizeof(pthread_t));
for (i = 0; i < num_thread; i++)
{
if(pthread_create(&thread[i], NULL, compute, (void*)i) != 0)
{
perror("Can't create thread!");
free(thread);
exit(-1);
}
}
for (i = 0; i < num_thread; i++)
pthread_join (thread[i], NULL);
moutput_itt(err, itt_max);
free(thread);
return 0;
}
```

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

IMO you somehow mix local and global use of the variable

What I can tell you is that

Without seing the call of this function I can't tell you more, sorry.

ZOPPO

matmul.h

matmul-main.c

matmul-setup.c

matmul-compute.c

matmul-output.c

Makefile

Next I'm a bit suprised why this doesn't produce any linker errors, but maybe your compiler/linker acts different than those I use. Generally a problem is that you instantiate the global

So you can do it somehow like this:

```
// mathmul.h
...
extern int global_thread_num;
...
```

```
// mathmul-compute.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include "matmul.h"
int global_thread_num = 0;
...
void* compute(void* thrd)
{
// replace all occurances of thread_num with global_thread_num in this function
}
int mcompute(int n, int seed, int itt_max, int num_thread, double *a, double *b)
{
global_num_thread = num_thread;
// you can replace all further occurances of thread_num with global_thread_num in this function to avoid confusion, but it's not necessary
...
}
```

BTW, you should change the instantiation in the header for the other global variables in

Hope that helps,

ZOPPO

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trialdouble *a;

do i need to change it to extern double *global_a ???

and since i'm accessing the global variable, do i actually still need to pass those variables?

For example:

```
// header.h
// (declaration in header allows use in every c-file which includes the header)
extern int global_int;
extern double* global_ptr;
extern int global_function( int value );
// cfile1.c
#include "header.h"
int global_int = 0; // instantiation
double local_double = 0.0; // instantiation of a local variable
int global_function( int value ); // implementation
{
// global pointer accessed here allthough it's not instantiated in this file
global_ptr = malloc( sizeof( double ) );
}
// cfile2.c
#include "header.h"
extern double local_double; // this tells the compilet/linker the variable exists but is instantiated elsewhere, so you can use it here
double* global_ptr = &local_double; // instantiation;
```

Hope that's helpful.

And, for the second question: If you simply use

ZOPPO

http://www.learncpp.com/cpp-tutorial/42-global-variables/

http://en.wikipedia.org/wiki/External_variable

http://comsci.liu.edu/~murali/c/StaticGlobal.htm

this means locally pass from main to setup, compute, and output.

which is better?

But you can implement a little struct to do it, i.e.:

```
struct compute_params
{
int num_threads;
int s;
}
void* compute(void* thrd)
{
compute_params* params = (compute_param*)thrd;
int s = params.s;
int num_threads = params.num_threads;
...
free( params );
}
int mcompute(int n, int seed, int itt_max, int num_thread, double *a, double *b)
{
compute_params* params;
...
for (i = 0; i < num_thread; i++)
{
params = malloc( sizeof( compute_params ) );
params.s = i;
params.num_threads = num_threads;
if(pthread_create(&thread[i], NULL, compute, (void*)params) != 0)
{
...
}
}
...
}
```

This way you can pass an arbitrary number of any kind of data to the thread function, so you don't need to have ZOPPO

```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include "matmul.h"
void srand48(long int seedval);
double drand48(void);
double *err;
struct compute_params
{
int s;
int n;
int itt_max;
int num_thread;
double *a;
double *b;
}
void* compute(void* thrd)
{
int from, to;
compute_params* params = (compute_params)* thrd;
int s = params.s;
int n = params.n;
int itt_max = params.itt_max;
int num_thread = params.num_thread;
double *a = params.a;
double *b = params.b;
int i, j;
double *t; // pointer to solution vector, space to be malloced
double *t1; // pointer to next itteraton of solution vector,
// space to be malloced
double *ttemp; // used to swap t1 and t at each itteration
int itt; // current itteration
double sum; // computes the inner products for A * t
double error; // max | t1[i] - t[i] |
double errori; // | t1[i] - t[i] |
if( (t=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t failed\n");
}
if( (t1=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t1 failed\n");
}
if( (err = (double*) malloc (sizeof (double) * itt_max)) == NULL)
{
fprintf(stderr," ERROR : malloc for err failed\n");
}
// Initialize t
for(i=0; i< n; i++)
{
t[i] = b[i];
}
if( s < num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread - 1;
}
else if ( s == num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread;
}
for(itt=from; itt<=to; itt++)
{
error=0.0;
for(i=0; i< n; i++)
{
sum = 0.0;
double *a_itt = a + n*i;
for(j=0; j< n; j++)
{
sum += *(a_itt++) * t[j];
}
t1[i] = sum + b[i];
errori = fabs(t1[i]-t[i]);
if(errori > error)
{
error=errori;
}
}
err[itt] = error;
ttemp = t1;
t1 = t;
t = ttemp;
}
pthread_exit(0);
free(params);
}
int mcompute(int n, int seed, int itt_max, int num_thread, double *a, double *b)
{
srand48((long int)seed);
float resultb[n];
int i, j; // indices into arrays
pthread_t* thread; // pointer to a group of threads
compute_params* params;
float **resulta = (float**)malloc(sizeof(float*)*n);
for(i=0; i< n; i++)
*(resulta+i) = (float*)malloc(sizeof(float)*n);
for(i=0; i< n; i++)
{
for(j=0; j< n; j++)
{
*(a+n*i+j) = 1.999 * (drand48() - 0.5) / n;
resulta[i][j] = *(a+n*i+j);
}
}
moutput_a(resulta, n);
// Generate vector b
for(i=0; i< n; i++)
{
b[i] = 10.0 * drand48();
resultb[i] = b[i];
}
moutput_b(resultb, n);
thread = (pthread_t*)malloc(num_thread*sizeof(pthread_t));
for (i = 0; i < num_thread; i++)
{
params = malloc(sizeof(compute_params));
params.s = i;
params.n = n;
params.itt_max = itt_max;
params.num_thread = num_thread;
params.a = a;
params.b = b;
if(pthread_create(&thread[i], NULL, compute, (void*)params) != 0)
{
perror("Can't create thread!");
free(thread);
exit(-1);
}
}
for (i = 0; i < num_thread; i++)
pthread_join (thread[i], NULL);
moutput_itt(err, itt_max);
free(thread);
return 0;
}
```

```
struct compute_params
{
int s;
int n;
int itt_max;
int num_thread;
double *a;
double *b;
}; // <-- here
```

ZOPPO
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include "matmul.h"
void srand48(long int seedval);
double drand48(void);
double *err;
struct compute_params
{
int s;
int n;
int itt_max;
int num_thread;
double *a;
double *b;
};
void* compute(void* thrd)
{
int from, to;
compute_params* params = (compute_params)* thrd; // struct to be passed
int s = params.s;
int n = params.n;
int itt_max = params.itt_max;
int num_thread = params.num_thread;
double *a = params.a;
double *b = params.b;
int i, j;
double *t; // pointer to solution vector, space to be malloced
double *t1; // pointer to next itteraton of solution vector,
// space to be malloced
double *ttemp; // used to swap t1 and t at each itteration
int itt; // current itteration
double sum; // computes the inner products for A * t
double error; // max | t1[i] - t[i] |
double errori; // | t1[i] - t[i] |
if( (t=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t failed\n");
}
if( (t1=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t1 failed\n");
}
if( (err = (double*) malloc (sizeof (double) * itt_max)) == NULL)
{
fprintf(stderr," ERROR : malloc for err failed\n");
}
// Initialize t
for(i=0; i< n; i++)
{
t[i] = b[i];
}
if( s < num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread - 1;
}
else if ( s == num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread;
}
for(itt=from; itt<=to; itt++)
{
error=0.0;
for(i=0; i< n; i++)
{
sum = 0.0;
double *a_itt = a + n*i;
for(j=0; j< n; j++)
{
sum += *(a_itt++) * t[j];
}
t1[i] = sum + b[i];
errori = fabs(t1[i]-t[i]);
if(errori > error)
{
error=errori;
}
}
err[itt] = error;
ttemp = t1;
t1 = t;
t = ttemp;
}
pthread_exit(0);
free(params);
}
int mcompute(int n, int seed, int itt_max, int num_thread, double *a, double *b)
{
srand48((long int)seed);
float resultb[n];
int i, j; // indices into arrays
pthread_t* thread; // pointer to a group of threads
compute_params* params;
float **resulta = (float**)malloc(sizeof(float*)*n);
for(i=0; i< n; i++)
*(resulta+i) = (float*)malloc(sizeof(float)*n);
for(i=0; i< n; i++)
{
for(j=0; j< n; j++)
{
*(a+n*i+j) = 1.999 * (drand48() - 0.5) / n;
resulta[i][j] = *(a+n*i+j);
}
}
moutput_a(resulta, n);
// Generate vector b
for(i=0; i< n; i++)
{
b[i] = 10.0 * drand48();
resultb[i] = b[i];
}
moutput_b(resultb, n);
thread = (pthread_t*)malloc(num_thread*sizeof(pthread_t));
for (i = 0; i < num_thread; i++)
{
params = malloc(sizeof(compute_params));
params.s = i;
params.n = n;
params.itt_max = itt_max;
params.num_thread = num_thread;
params.a = a;
params.b = b;
if(pthread_create(&thread[i], NULL, compute, (void*)params) != 0)
{
perror("Can't create thread!");
free(thread);
exit(-1);
}
}
for (i = 0; i < num_thread; i++)
pthread_join (thread[i], NULL);
moutput_itt(err, itt_max);
free(thread);
return 0;
}
```

In C (that's different in C++) you cannot use a struct directly as a variable type. You have either to use the keyword

```
struct compute_params
{
int s;
int n;
int itt_max;
int num_thread;
double *a;
double *b;
};
// need to use struct keyword here
struct compute_params params;
```

or```
typedef struct s_compute_params
{
int s;
int n;
int itt_max;
int num_thread;
double *a;
double *b;
} compute_params;
// no need to use struct keyword since it's a typedef
compute_params params;
```

ZOPPO
```
matmul_compute.c: In function `compute':
matmul_compute.c:25: warning: dereferencing `void *' pointer
matmul_compute.c:25: error: void value not ignored as it ought to be
matmul_compute.c:26: error: request for member `s' in something not a structure or union
matmul_compute.c:27: error: request for member `n' in something not a structure or union
matmul_compute.c:28: error: request for member `itt_max' in something not a structure or union
matmul_compute.c:29: error: request for member `num_thread' in something not a structure or union
matmul_compute.c:30: error: request for member `a' in something not a structure or union
matmul_compute.c:31: error: request for member `b' in something not a structure or union
matmul_compute.c: In function `mcompute':
matmul_compute.c:142: error: request for member `s' in something not a structure or union
matmul_compute.c:143: error: request for member `n' in something not a structure or union
matmul_compute.c:144: error: request for member `itt_max' in something not a structure or union
matmul_compute.c:145: error: request for member `num_thread' in something not a structure or union
matmul_compute.c:146: error: request for member `a' in something not a structure or union
matmul_compute.c:147: error: request for member `b' in something not a structure or union
```

for the below code:

```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include "matmul.h"
void srand48(long int seedval);
double drand48(void);
double *err;
typedef struct s_compute_params
{
int s;
int n;
int itt_max;
int num_thread;
double *a;
double *b;
} compute_params;
void* compute(void* thrd)
{
int from, to;
compute_params* params = (compute_params)* thrd; // struct to be passed
int s = params.s;
int n = params.n;
int itt_max = params.itt_max;
int num_thread = params.num_thread;
double *a = params.a;
double *b = params.b;
int i, j;
double *t; // pointer to solution vector, space to be malloced
double *t1; // pointer to next itteraton of solution vector,
// space to be malloced
double *ttemp; // used to swap t1 and t at each itteration
int itt; // current itteration
double sum; // computes the inner products for A * t
double error; // max | t1[i] - t[i] |
double errori; // | t1[i] - t[i] |
if( (t=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t failed\n");
}
if( (t1=(double *)malloc(sizeof(double)*n)) == NULL)
{
fprintf(stderr," ERROR : malloc for t1 failed\n");
}
if( (err = (double*) malloc (sizeof (double) * itt_max)) == NULL)
{
fprintf(stderr," ERROR : malloc for err failed\n");
}
// Initialize t
for(i=0; i< n; i++)
{
t[i] = b[i];
}
if( s < num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread - 1;
}
else if ( s == num_thread)
{
from = (s * (itt_max + 1))/num_thread;
to = ((s + 1) * (itt_max + 1))/num_thread;
}
for(itt=from; itt<=to; itt++)
{
error=0.0;
for(i=0; i< n; i++)
{
sum = 0.0;
double *a_itt = a + n*i;
for(j=0; j< n; j++)
{
sum += *(a_itt++) * t[j];
}
t1[i] = sum + b[i];
errori = fabs(t1[i]-t[i]);
if(errori > error)
{
error=errori;
}
}
err[itt] = error;
ttemp = t1;
t1 = t;
t = ttemp;
}
pthread_exit(0);
free(params);
}
int mcompute(int n, int seed, int itt_max, int num_thread, double *a, double *b)
{
srand48((long int)seed);
float resultb[n];
int i, j; // indices into arrays
pthread_t* thread; // pointer to a group of threads
compute_params* params;
float **resulta = (float**)malloc(sizeof(float*)*n);
for(i=0; i< n; i++)
*(resulta+i) = (float*)malloc(sizeof(float)*n);
for(i=0; i< n; i++)
{
for(j=0; j< n; j++)
{
*(a+n*i+j) = 1.999 * (drand48() - 0.5) / n;
resulta[i][j] = *(a+n*i+j);
}
}
moutput_a(resulta, n);
// Generate vector b
for(i=0; i< n; i++)
{
b[i] = 10.0 * drand48();
resultb[i] = b[i];
}
moutput_b(resultb, n);
thread = (pthread_t*)malloc(num_thread*sizeof(pthread_t));
for (i = 0; i < num_thread; i++)
{
params = malloc(sizeof(compute_params));
params.s = i;
params.n = n;
params.itt_max = itt_max;
params.num_thread = num_thread;
params.a = a;
params.b = b;
if(pthread_create(&thread[i], NULL, compute, (void*)params) != 0)
{
perror("Can't create thread!");
free(thread);
exit(-1);
}
}
for (i = 0; i < num_thread; i++)
pthread_join (thread[i], NULL);
moutput_itt(err, itt_max);
free(thread);
return 0;
}
```

```
compute_params* params = (compute_params)* thrd
```

It has to be```
compute_params* params = (compute_params*) thrd
```

ZOPPO
```
matmul_compute.c: In function `compute':
matmul_compute.c:26: error: request for member `s' in something not a structure or union
matmul_compute.c:27: error: request for member `n' in something not a structure or union
matmul_compute.c:28: error: request for member `itt_max' in something not a structure or union
matmul_compute.c:29: error: request for member `num_thread' in something not a structure or union
matmul_compute.c:30: error: request for member `a' in something not a structure or union
matmul_compute.c:31: error: request for member `b' in something not a structure or union
matmul_compute.c: In function `mcompute':
matmul_compute.c:142: error: request for member `s' in something not a structure or union
matmul_compute.c:143: error: request for member `n' in something not a structure or union
matmul_compute.c:144: error: request for member `itt_max' in something not a structure or union
matmul_compute.c:145: error: request for member `num_thread' in something not a structure or union
matmul_compute.c:146: error: request for member `a' in something not a structure or union
matmul_compute.c:147: error: request for member `b' in something not a structure or union
```

```
int s = params->s;
int n = params->n;
int itt_max = params->itt_max;
int num_thread = params->num_thread;
double *a = params->a;
double *b = params->b;
```

ZOPPO
```
compute_params params;
params.s = i;
compute_params* params_ptr = ¶ms;
params_ptr->s = i;
```

```
compute_params* params;
for (i = 0; i < num_thread; i++)
{
params = malloc(sizeof(compute_params));
params->s = i;
params->n = n;
params->itt_max = itt_max;
params->num_thread = num_thread;
params->a = a;
params->b = b;
if(pthread_create(&thread[i], NULL, compute, (void*)params) != 0)
{
perror("Can't create thread!");
free(thread);
exit(-1);
}
}
```

if i use this, i'll get the similar erros as above:

```
compute_params* params;
for (i = 0; i < num_thread; i++)
{
params = malloc(sizeof(compute_params));
params.s = i;
params.n = n;
params.itt_max = itt_max;
params.num_thread = num_thread;
params.a = a;
params.b = b;
if(pthread_create(&thread[i], NULL, compute, (void*)params) != 0)
{
perror("Can't create thread!");
free(thread);
exit(-1);
}
}
```

But in your case the pointer's name is 'param', therefor the first version is correct.

C

From novice to tech pro — start learning today.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.