I have some issues with my code. I need to pass an int array to a thread witch will calculate the ^2 of every int of the array.
My code:
#include <pthread.h> //etc.
#define SIZE 1024
static void * function_thread(void *arg){
int *loc = (int *)arg;
// i tried also int loc[SIZE] = (int *)arg; but won' compile ion' t know why
for (int i = 0; i < SIZE; i++) {
loc[i] = loc[i] * loc[i];
// tried also loc[i] = (*(int *)arg) * (*(int *)arg);
printf("loc[%d]^2 = %d\n",i, loc[i]);
}
return (void *)loc;
}
int main(int argc, char const *argv[]) {
int x[SIZE];
void (*res[SIZE]);
int y[SIZE];
for (int i = 0; i < SIZE; i++) {
x[i] = i;
}
pthread_t thread_1;
pthread_create(&thread_1,NULL,function_thread,x);
pthread_join(thread_1, &res);
for(int i = 0; i < SIZE; i++){
y[i] = res[i];
}
}
So i have few questions:
There is something wrong already in the thread function? is giving me loc[i] = 0 for each i.What's the problem?
why the initialization of *int loc[SIZE] = (int * )arg; doesnìt work?
I have seen that
int x;
int * result;
...
pthread_join(someThread, &result);
x = result + result;
this works.But why? isn't x and result types different?
Thanks you in advice and wish you a good day!
Related
It's been a few hours and i can't seem to understand the issue. Build this program to count from 1 - 10. The goal of this program is to use multithreading and dynamically split the array depending on how many threads it requested. Problem is the first 2 threads are being skipped and the last thread is doing most of th e process. I suspect it's the for loop that creates the threads.
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
typedef struct
{
int *array;
int batch;
int start;
int end;
} Parameter;
void *method(void *p)
{
Parameter *param = (Parameter *)p;
for (int i = param->start; i < param->end; i++)
{
printf("Start:%d\tEnd:%d\tIndex:%d\tValue:%d\n", param->start, param->end, i,param->array[i]);
}
}
int main(int argc, char **argv)
{
// Getting the user input
int array_length = atoi(argv[1]);
int batches = atoi(argv[2]);
printf("User specified Array:%d\tBatch:%d\n", array_length, batches);
// Creating an array
int *array = (int *)calloc(array_length, sizeof(int));
// Fill it up with some data
for (int i = 0; i < array_length; i++)
{
array[i] = i;
}
// Determine the Batches
int batch_size = array_length / batches;
int remainder = array_length % batches;
printf("%d\n", batch_size);
printf("%d\n", remainder);
int start = 0;
int end = 0;
int index =0;
// List of parameters
Parameter *param = (Parameter *)calloc(batches, sizeof(Parameter));
pthread_t *threads = (pthread_t *)calloc(batches, sizeof(pthread_t));
// Loop through each batch.
for (int i = 0; i < batches; i++)
{
printf("\n\nBatch number -> %d\n", i);
end = start + batch_size;
if (remainder > 0)
{
remainder --;
end ++;
}
// Fill the parameters
param[i].array = array;
param[i].end = end;
param[i].start = start;
param[i].batch = i;
// Call the thread.
pthread_create(threads + index, NULL, method, (void *)¶m[i]);
index++;
start = end;
}
for (int i = 0; i < batches; i++)
{
pthread_join(threads[i], NULL);
}
free(param);
free(threads);
free(array);
return 0;
}
Been playing with the index of the for loop(line 57) as i'm certain it's the cause of the issue. been getting some results but the main problem still persisted.
Code Works as intended. I'm a dumbas who didn't put the printf in the void function. like so:
void *method(void *p) {
Parameter *param = (Parameter *)p;
printf("\n\nBatch number -> %d\n", param->batch); //<-- moved from main method
for (int i = param->start; i < param->end; i++)
{
printf("Start:%d\tEnd:%d\tIndex:%d\tValue:%d\n", param->start, param->end, i,param->array[i]);
} }
Thanks for pointing it out that the program works
I am trying to multiply two matrices using a different thread for each member of the resultant matrix. I have this code:
struct data{
int p;
int linie[20];
int coloana[20];
};
void *func(void *args){
struct data *st = (struct data *) args;
int c = 0;
for(int k = 0; k < st->p; k++){
c += st->linie[k] * st->coloana[k];
}
char *rez = (char*) malloc(5);
sprintf(rez, "%d", c);
return rez;
}
int main(int argc, char *argv[]){
int n = 2;
int m = 2;
int A[2][2] = {{1, 2},
{4, 5}};
int B[2][2] = {{7, 3},
{7, 5}};
int C[n][m];
char *res[n * m];
char *rez[n * m];
pthread_t threads[n * m];
int count = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
struct data st;
st.p = 2;
for(int x = 0; x < st.p; x++){
st.linie[x] = A[i][x];
st.coloana[x] = B[x][j];
}
pthread_create(&threads[count], NULL, func, &st);
count++;
}
}
for(int i = 0; i < n * m; i++){
pthread_join(threads[i], (void**) &rez[i]);
printf("%d ", atoi(rez[i]));
}
return 0;
}
But the correct result is never put into rez[i]. For example I get output "63 37 37 37".
The code works perfectly if I don't choose to wait for every thread to finish, i.e. I put that pthread_join right after pthread_create in the nested for loop. What should I do?
Thanks for reading!
Your first threading problem is here:
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
struct data st;
st.p = 2;
for(int x = 0; x < st.p; x++){
st.linie[x] = A[i][x];
st.coloana[x] = B[x][j];
}
pthread_create(&threads[count], NULL, func, &st);
count++;
}
}
All the threads get passed a pointer to the same variable, &st, which goes out of scope after each call to pthread_create(). You need to ensure that each thread gets its own variable, and that the variable lasts until the thread exits.
To fix this, for example, you could try:
struct data st[n * m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
st[count].p = 2;
for (int x = 0; x < st[count].p; x++)
{
st[count].linie[x] = A[i][x];
st[count].coloana[x] = B[x][j];
}
int rc = pthread_create(&threads[count], NULL, func, &st[count]);
if (rc != 0)
…report pthread creation error…
count++;
}
}
This gives each thread its own struct data to work on, and the structure outlasts the pthread_join() loop.
I'm not completely that it is a good scheme to make one copy of the relevant parts of the two arrays for each thread. It's not too painful at size 2x2, but at 20x20, it begins to be painful. The threads should be told which row and column to process, and should be given pointers to the source matrices, and so on. As long as no thread modifies the source matrices, there isn't a problem reading the data.
Updated answer which replaces the previous invalid code related to pthread_join() (as noted by oftigus in a comment) with this working code. There's a reason I normally test before I post!
On the whole, casts like (void **) should be avoided in the pthread_join() loop. One correct working way to handle this is:
for (int i = 0; i < n * m; i++)
{
void *vp;
int rc = pthread_join(threads[i], &vp);
if (rc == 0 && vp != NULL)
{
rez[i] = vp;
printf("(%s) %d ", rez[i], atoi(rez[i]));
free(rez[i]);
}
}
putchar('\n');
This passes a pointer to a void * variable to pthread_join(). If it finds the information for the requested thread, then pthread_join() makes that void * variable hold the value returned by the thread function. This can then be used as shown — note the error handling (though I note that the example in the POSIX specification for pthread_join()ignores the return value from pthread_join() with a (void) cast on the result).
I don't see where you use res or C.
The result I get is:
(21) 21 (13) 13 (63) 63 (37) 37
where the value in parentheses is a string and the value outside is converted by atoi(). That looks like the correct answer for multiplying A by B (in that order).
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct data
{
int p;
int linie[20];
int coloana[20];
};
static void *func(void *args)
{
struct data *st = (struct data *)args;
int c = 0;
for (int k = 0; k < st->p; k++)
{
c += st->linie[k] * st->coloana[k];
}
char *rez = (char *)malloc(5);
sprintf(rez, "%d", c);
return rez;
}
int main(void)
{
int n = 2;
int m = 2;
int A[2][2] = {{1, 2}, {4, 5}};
int B[2][2] = {{7, 3}, {7, 5}};
char *rez[n * m];
pthread_t threads[n * m];
int count = 0;
struct data st[n * m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
st[count].p = 2;
for (int x = 0; x < st[count].p; x++)
{
st[count].linie[x] = A[i][x];
st[count].coloana[x] = B[x][j];
}
int rc = pthread_create(&threads[count], NULL, func, &st[count]);
if (rc != 0)
{
fprintf(stderr, "Failed to create thread %d for cell C[%d][%d]\n", count, i, j);
exit(1);
}
count++;
}
}
for (int i = 0; i < n * m; i++)
{
void *vp;
int rc = pthread_join(threads[i], &vp);
if (rc == 0 && vp != NULL)
{
rez[i] = vp;
printf("(%s) %d ", rez[i], atoi(rez[i]));
free(rez[i]);
}
}
putchar('\n');
return 0;
}
I know that you can return a pointer to the first element of an array in c by doing:
#include <stdlib.h>
#include <stdio.h>
int *my_func(void);
int main(void)
{
int *a;
int i;
a = my_func();
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, a[i]);
}
free(a);
return 0;
}
int *my_func(void)
{
int *array;
int i;
array = calloc(3, sizeof(int));
for(i = 0; i < 3; i++)
{
array[i] = i;
}
return array;
}
But if I wanted to return two pointers instead of just one, I tried:
#include <stdlib.h>
#include <stdio.h>
int *my_func(int *);
int main(void)
{
int *a;
int *b;
int i;
a = my_func(b);
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, a[i]);
printf("b[%d] = %d\n", i, b[i]);
}
free(a);
free(b);
return 0;
}
int *my_func(int *array2)
{
int *array;
int i;
array = calloc(3, sizeof(int));
array2 = calloc(3, sizeof(int));
for(i = 0; i < 3; i++)
{
array[i] = i;
array2[i] = i;
}
return array;
}
But this seg faults on the printf for b. I ran it through valgrind and it says that there is an invalid read of size 4 at the printf for b, which means I'm doing something screwy with the b pointer. I was just wondering what the best way to "return" a second pointer to an array was in c? I'm asking because I would like to do it this way rather than use a global variable (I'm not opposed to them, as they are useful at times, I just prefer not to use them if possible). The other questions I've seen on this site used statically allocated arrays, but I haven't yet stumbled across a question that was using dynamic allocation. Thanks in advance!
I can think of three (and a half) simple ways to return multiple items of any kind from a C-function. The ways are described below. It looks like a lot of text, but this answer is mostly code, so read on:
Pass in an output argument as you have done, but do it correctly. You have to allocate space for an int * in main() and then pass the pointer to that to my_func.
In main():
a = my_func(&b);
my_func() becomes:
int *my_func(int **array2)
{
int *array;
int i;
array = calloc(3, sizeof(int));
*array2 = calloc(3, sizeof(int));
for(i = 0; i < 3; i++)
{
array[i] = i;
(*array2)[i] = i;
}
return array;
}
Make your function allocate array of two pointers to the int arrays you are trying to allocate. This will require an additional allocation of two int pointers, but may be worth the trouble.
main() then becomes:
int main(void)
{
int **ab;
int i;
ab = my_func(b);
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, ab[0][i]);
printf("b[%d] = %d\n", i, ab[1][i]);
}
free(ab[0]);
free(ab[1]);
free(ab);
return 0;
}
my_func() then becomes:
int **my_func(void)
{
int **arrays;
int i, j;
arrays = calloc(2, sizeof(int *));
arrays[0] = calloc(3, sizeof(int));
arrays[1] = calloc(3, sizeof(int));
for(j = 0; j < 2; j++)
{
for(i = 0; i < 3; i++)
{
arrays[j][i] = i;
}
}
return arrays;
}
Return a structure or structure pointer. You will need to define the structure, and decide whether you want to return the structure itself, a newly allocated pointer to it, or pass it in as a pointer and have my_func() fill it in for you.
The structure definition would look something like this:
struct x
{
int *a;
int *b;
}
You would then rephrase your current functions as one of the following three options:
Direct passing of structure (not recommended for general use):
int main(void)
{
struct x ab;
int i;
ab = my_func();
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, ab.a[i]);
printf("b[%d] = %d\n", i, ab.b[i]);
}
free(ab.a);
free(ab.b);
return 0;
}
struct x my_func(void)
{
struct x ab;
int i;
ab.a = calloc(3, sizeof(int));
ab.b = calloc(3, sizeof(int));
for(i = 0; i < 3; i++)
{
ab.a[i] = i;
ab.b[i] = i;
}
return ab;
}
Return a pointer to a dynamically allocated structure (this is a pretty good option in general):
int main(void)
{
struct x *ab;
int i;
ab = my_func();
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, ab->a[i]);
printf("b[%d] = %d\n", i, ab->b[i]);
}
free(ab->a);
free(ab->b);
free(ab);
return 0;
}
struct x *my_func(void)
{
struct x *ab;
int i;
ab = malloc(sizeof(struct x));
ab->a = calloc(3, sizeof(int));
ab->b = calloc(3, sizeof(int));
for(i = 0; i < 3; i++)
{
ab->a[i] = i;
ab->b[i] = i;
}
return ab;
}
Allocate the structure in main() and fill it in in my_func via a passed-in pointer. This option is often used in a way where my_func would allocate the structure if you pass in a NULL pointer, otherwise it would return whatever you passed in. The version of my_func shown here has no return value for simplicity:
int main(void)
{
struct x ab;
int i;
my_func(&ab);
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, ab.a[i]);
printf("b[%d] = %d\n", i, ab.b[i]);
}
free(ab.a);
free(ab.b);
return 0;
}
void my_func(struct x *ab)
{
int i;
ab->a = calloc(3, sizeof(int));
ab->b = calloc(3, sizeof(int));
for(i = 0; i < 3; i++)
{
ab->a[i] = i;
ab->b[i] = i;
}
return;
}
For all the examples shown here, don't forget to update the declaration of my_func at the top of the file, although I am sure any reasonable compiler will remind you if you forget.
Keep in mind also that these are just three options I pulled out of my brain at a moments notice. While they are likely to cover 99% of any use cases you may come up against any time soon, there are (probably lots of) other options out there.
Function parameters are its local variables. Functions deal with copies of values of the supplied arguments.
You can imagine your function definition and its call the following way
a = my_func(b);
int *my_func( /* int *array2 */ )
{
int *array2 = b;
//...
}
So any changes of the local variable array2 inside the function do not influence on the original argument b.
For such a function definition you have to pass the argument by reference that is the function should be declared like
int *my_func( int **array2 );
^^
There are many ways to implement the function. You could define a structure of two pointers as for example
struct Pair
{
int *a;
int *b;
};
and use it as the return type of the function
struct Pair my_func( void );
Another approach is to pass to the function an array of pointers to the original pointers.
The function can look as it is shown in the demonstrative program.
#include <stdio.h>
#include <stdlib.h>
size_t multiple_alloc( int ** a[], size_t n, size_t m )
{
for ( size_t i = 0; i < n; i++ ) *a[i] = NULL;
size_t k = 0;
for ( ; k < n && ( *a[k] = malloc( m * sizeof( int ) ) ) != NULL; k++ )
{
for ( size_t i = 0; i < m; i++ ) ( *a[k] )[i] = i;
}
return k;
}
#define N 2
#define M 3
int main(void)
{
int *a;
int *b;
multiple_alloc( ( int ** [] ) { &a, &b }, N, M );
if ( a )
{
for ( size_t i = 0; i < M; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
}
if ( b )
{
for ( size_t i = 0; i < M; i++ ) printf( "%d ", b[i] );
putchar( '\n' );
}
free( a );
free( b );
return 0;
}
The program output is
0 1 2
0 1 2
#include <stdlib.h>
#include <stdio.h>
int *my_func(int **);
int main(void)
{
int *a;
int *b;
int i;
b=(int *)malloc(sizeof(int));
a = my_func(&b);
for(i = 0; i < 3; i++)
{
printf("a[%d] = %d\n", i, a[i]);
printf("b[%d] = %d\n", i, b[i]);
}
free(a);
free(b);
return 0;
}
int *my_func(int **array2)
{
int *array;
int i;
array = calloc(3, sizeof(int));
*array2 =calloc(3,sizeof(int));
for(i = 0; i < 3; i++)
{
array[i] = i;
*((*array2)+i)=i;//or (*array2)[i]
}
return array;
}
Pass the pointer by reference. Because its the same logic as, to manipulate an integer block you need to pass a pointer to it. Similarly, to manipulate a pointer, you will have to pass a pointer to it(i.e. pointer to pointer).
I'm making a program which dynamically creating 2d array.but it's showing the error which I mentioned on the title. I'm using Visual Studio 2015.
// last.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include "stdlib.h"
double selectionSort(int * number, int number_count);
void print2d(int ** array, int rows, int cols);
void twodarray();
void main(int argc, char* argv[])
{
int num_count = 10000;
int num[10000];
for (int i = 0; i < num_count; i++)
{
num[i] = rand();
}
double sortTime = selectionSort(num, num_count);
printf("Total Runtime is: %.0f milliseconds. \n", sortTime * 1000);
twodarray();
getchar();
}
double selectionSort(int * number, int number_count)
{
clock_t start, end;
double duration;
int min;
start = clock();
for (int i = 0; i < number_count - 1; i++)
{
min = i;
for (int j = i + 1; j < number_count; j++)
{
if (number[min] > number[j])
{
min = j;
}
}
if (min != i)
{
int temp = number[min];
number[min] = number[i];
number[i] = temp;
}
}
end = clock();
return duration = (double)(end - start) / CLOCKS_PER_SEC;
}
void print2d(int ** array, int rows, int cols)
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0, j < cols; j++;)
{
printf("%10d ", array[i][j]);
}
puts("");
}
}
void twodarray()
{
int **twod;
int rows = 10;
twod = malloc(rows * sizeof(int));
int i,cols = 10;
for (i = 0; i < rows; i++)
{
twod[i] = malloc(cols*sizeof(int));
print2d(twod, rows, cols);
}
for (i = 0; rows; i++)
{
free(twod[i]);
free(twod);
}
}
In c++ you need to cast when assigining a void * pointer to another type of pointer. But in c++ you should not use malloc(), instead use
int **twod = new int *[rows];
If you didn't mean to write a c++ program, rename the file. Change the extension from .cpp to .c.
Your allocation is wrong too, as pointed out by #KeineLust here.
This is wrong:
int **twod;
int rows = 10;
twod = malloc(rows * sizeof(int));
You need to reserve space for n pointers to int, not for n ints, change to
twod = malloc(rows * sizeof(int *));
And here:
for (j = 0, j < cols; j++;)
^ ^
Use a semicolon instead of a comma and also remove the last semicolon.
Another problem:
for (i = 0; rows; i++)
{
free(twod[i]);
free(twod); /* Don't free twod in the loop, one malloc -> one free */
}
And as pointed out by Nicat and Iharob, it seems that you are mixing C and C++, use the proper extension (.c)
I'm trying out Multi-threading in C for the first time, and I seem to be doing something wrong which I hope you could help me with. Here is my code:
#include "stdafx.h"
#define MAX_THREADS 2
int a[100000];
int b[200000];
void startThreads();
DWORD WINAPI populateArrayA(LPVOID data)
{
int i;
int* pA = (int*)data;
for(i = 0; i < sizeof(a) / sizeof(int); i++)
{
*pA = i;
pA++;
}
return 0;
}
DWORD WINAPI populateArrayB(LPVOID data)
{
int i;
int* pB = (int*)data;
for(i = 0; i < sizeof(b) / sizeof(int); i++)
{
*pB = i;
pB++;
}
return 0;
}
void startThreads()
{
HANDLE threads[MAX_THREADS];
DWORD threadIDs[MAX_THREADS];
threads[0] = CreateThread(NULL,0,populateArrayA,a,0,&threadIDs[0]);
threads[1] = CreateThread(NULL,0,populateArrayB,b,0,&threadIDs[1]);
if(threads[0] && threads[1])
{
printf("Threads Created. (IDs %d and %d)",threadIDs[0],threadIDs[1]);
}
WaitForMultipleObjects(MAX_THREADS,threads,true,0);
}
int main(int argc, char* argv[])
{
int i;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
startThreads();
return 0;
}
In this code, Array "b" seems to populate fine, however Array "a" does not. Sorry if the answer is something stupid!
EDIT: I just tried again, and both arrays are all '0's. Not quite sure what's going on. I'm using Visual Studio in case it's a debugging issue or something.
Cheers.
The last parameter of WaitForMultipleObjects must be INFINITE, not 0.
With 0, the function returns immediatly.