Casting int function to void* - c

I have a problem with casting returned integer value to void pointer. Have tried some options from this site but my problem seems to still haven't been resolved. Although the program compiles with no code errors I'm getting a segmentation fault. Am I blind and are there some mistakes in my code?
#include<pthread.h>
#include<stdio.h>
#include<stdint.h>
int ackermann(int a, int b)
{
if(a==0)
return a+1;
else if(a>0 && b==0)
{
return ackermann(a-1, 1);
}
else if(a>0 && b>0)
{
return ackermann(a-1,ackermann(a,(b-1)));
}
}
int main(int argc, char* argv[])
{
int a = atoi(argv[1]);
int b = atoi(argv[2]);
int c = ackermann(a,b);
void *ptr = &c;
pthread_t mythread;
if(pthread_create(&mythread, NULL, ptr, NULL))
{
printf("Could not create a thread\n");
}
pthread_exit(NULL);
return 0;
}

As was mentioned in the comments, you're not actually calling the function ackermann in a separate thread. What you are doing is calling the function directly from main, storing the result in an int, and passing a pointer to that int as the third parameter to pthread_create, which is supposed to be a pointer to the function to run.
Right now, ackermann does not have the appropriate signature to be passed to pthread_create. A function that starts a new thread should be declared like this:
void *my_thread_function(void *parameter);
Given that ackermann is called recursively, it would be cleaner to pass a a wrapper function to pthread_create and have that wrapper call ackermann rather than modifying ackermann to match the above signature.
Because you need to pass multiple parameters to your thread function, you'll need to create a struct which contains all the parameters and pass a pointer to that struct to thread function.
You can also store the return value in this struct so that the function which started the thread has access to it.
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
int ackermann(int a, int b)
{
if(a==0) {
return a+1;
} else if(a>0 && b==0) {
return ackermann(a-1, 1);
} else if(a>0 && b>0) {
return ackermann(a-1,ackermann(a,(b-1)));
}
// if none of the above conditions are true, no value is returned
// better check for this
}
struct ackermann_params {
int a;
int b;
int result;
};
void *ackermann_thr(void *arg)
{
struct ackermann_params *params = arg;
params->result = ackermann(params->a, params->b);
return NULL;
}
int main(int argc, char* argv[])
{
struct ackermann_params params;
if (argc < 3) {
printf("invalid number of arguments\n");
exit(1);
}
params.a = atoi(argv[1]);
params.b = atoi(argv[2]);
pthread_t mythread;
if(pthread_create(&mythread, NULL, ackermann_thr, &params))
{
perror("Could not create a thread\n");
exit(1);
}
if (pthread_join(mythread, NULL)) {
perror("join failed\n");
exit(1);
}
printf("result=%d\n", params.result);
return 0;
}

Related

Bounded buffer sharing with Pthread and mutex locks busy waiting

I am trying to create a producer consumer queue, using mutex locks, creating busy waiting between threads. My Main file takes X amount of integer arguments, pushes them onto a BOUNDED BUFFER of size 50. I am using a while loop to do this since you do not know the amount before hand. I am not sure when and where to create my producer thread.
NOTE: Main is a "producer" in the sense it fills the buffer, but my actual producer function is going to pass onto my consumer function later in my code, so disregard the names. Main is going to "Produce" numbers by pushing and producer is going to pop those numbers for later use. My question is where and when do I make my Pthread_create in my code for producer and am I using the Mutex locks correctly to have synchronization between the two threads?
#include <pthread.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#define BUFFER_SIZE (50)
typedef struct {
int buffer[BUFFER_SIZE];
int count;
int top;
int next;
pthread_mutex_t count_lock;
} prodcons;
void pc_init(prodcons *pc);
int pc_pop(prodcons *pc);
void pc_push(prodcons *pc, int val);
void factor2pc(prodcons *pc, int number);
void *producer(void *data);
void *consumer(void *data);
int main(int argc, char *argv[])
{
int index = 1;
int num;
prodcons pc_nums;
//pthread_t tid[argc - 1];
pthread_t tid;
pthread_attr_t attr;
if (argc < 2) {
fprintf(stderr, "usage: No arguments\n");
return -1;
}
if (atoi(argv[1]) <= 0)
{
fprintf(stderr, "%d not > 0 or you must provide a positive integer.\n", atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
pc_init(&pc_nums);
//DO I PUT THIS HERE or WHILE LOOP?
pthread_create(&tid, &attr, *producer, &pc_nums);
while (index < argc)
{
num = atoi(argv[index]);
pc_push(&pc_nums, num);
index++;
}
}
void *producer(void *data)
{
prodcons *dataStruct = data;
while (dataStruct->count < BUFFER_SIZE)
{
number = pc_pop(data);
//This print is just here to make sure I am correctly "poping" from buffer
printf("%d\n", number);
}
}
void pc_init(prodcons *pc)
{
pc->count = 0;
pc->top = 0;
pc->next = 0;
if (pthread_mutex_init(&pc->count_lock, NULL) != 0)
{
printf("\n mutex init has failed\n");
}
}
int pc_pop(prodcons *pc)
{
int val;
pthread_mutex_lock(&pc->count_lock);
if (pc->count > pc->top)
{
val = pc->buffer[pc->count];
printf("%d\n", val);
pc->buffer[pc->count] = 0;
pc->count--;
}
pthread_mutex_unlock(&pc->count_lock);
return val;
}
void pc_push(prodcons *pc, int val)
{
pthread_mutex_lock(&pc->count_lock);
if (pc->count < BUFFER_SIZE)
{
pc->buffer[pc->count] = val;
pc->count++;
}
pthread_mutex_unlock(&pc->count_lock);
}
My question is where and when do I make my Pthread_create in my code for producer and am I using the Mutex locks correctly to have synchronization between the two threads?
As long as all is properly initialized and synchronized, you can put the pthread_create() call wherever you want, including where it's placed in the given program. But at least two things are wrong:
pc_pop() behaves undefined (by return of an uninitialized value) if there is no number in the buffer to pop.
Since dataStruct->count is accessed by producer() without locking, the declaration should be _Atomic(int) count;.

How to pass an array properly to a threaded function with a structure

Ive been beating my head against the wall for days about this because I cant seem to find a good solution to this issue. I need to pass two arrays into a threaded function using a structure. One array is the structure Im needing to sum and the other is where the result of that summation needs to be stored and then I need to sum them one final time in the main program to get the total value.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define NUMBER_OF_THREADS 2
typedef struct
{
double s[NUMBER_OF_THREADS];
double a[];
int tid;
} parmListType;
void *sum_arr(void *parms)
{
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t threads[NUMBER_OF_THREADS];
int status, i;
double arr[1000000]={};
double sum[NUMBER_OF_THREADS];
printf("debug_size_arr: %ld\n",sizeof(arr)/sizeof(double));
for(int i=0;i<sizeof(arr)/sizeof(double);i++)
{
arr[i]=i;
}
parmListType *parms;
for(i=0; i<NUMBER_OF_THREADS; i++)
{
printf("debug: Main here. Creating thread %d\n", i);
// dynamically create a structure to hold the parameter list
parms = (parmListType *)malloc( sizeof(parmListType));
//printf("debug_sizeof_paramA: %ld\n",sizeof(parms->a));
//parms->s[NUMBER_OF_THREADS/sizeof(double)]= *sum;
parms->tid = i;
status = pthread_create(&threads[i], NULL, sum_arr, (void *) parms);
if(status != 0)
{
printf("oops. pthread_create returned error code %d\n", status);
exit(-1);
}
printf("first for\n");
}
for(i=0; i<NUMBER_OF_THREADS; i++)
{
status=pthread_join(threads[i], NULL);
}
exit(0);
}
//// there are loads of errors in this code, I need guidance about how Im
////supposed to set this up right.
You can do st similar to the below:
struct ThreadArgs
{
int type;
//others
};
void* Thread(void* thread_args)
{
int type;
pthread_detach(pthread_self());
type = ((struct ThreadArgs *) thread_args)->type;
return NULL;
}
int main()
{
pthread_t thread_id;
struct ThreadArgs* thread_args;
thread_args = (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs));
if (thread_args == NULL)
PanicWithError("malloc() failed");
thread_args->type = 1;
if (pthread_create(&thread_id, NULL, Thread, (void *) thread_args) != 0)
PanicWithError("pthread_create() failed");
while (1)
{}
return 0;
}

Dynamic array and functionalize malloc [duplicate]

This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 6 years ago.
I try to malloc an array functionally, and this function also can check whether the memory is enough or not.
The first code block can't work.
When it executes " *pi = 5 ", the compiler shows this error message " Thread 1: EXC_BAD_ACCESS(code=1, address=0x0) " .
#include <stdio.h>
#include <stdlib.h>
void malloc_and_check(int *var)
{
if(!(var = (int*)malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
exit(EXIT_FAILURE);
}
}
int main(int argc, const char * argv[])
{
int *pi;
malloc_and_check(pi);
*pi = 5;
printf("%d", *pi);
free(pi);
}
However, the codes as below can work normally.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
int *pi;
if(!(pi = (int*)malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
exit(EXIT_FAILURE);
}
*pi = 5;
printf("%d", *pi);
free(pi);
}
What are the difference between them? Thanks!
When you pass the int * var into malloc_and_check you are updating a local copy of the pointer so the original is unchanged. You can fix this in two ways:
(a) return the pointer from malloc_and_check
int * malloc_and_check()
{
int * var = 0;
if(!(var = (int*)malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
return 0;
}
return var;
}
Then you would call it as
pi = malloc_and_check();
(b) pass in a pointer to the pointer
void malloc_and_check(int ** var)
{
if(!( *var = (int*)malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
exit(EXIT_FAILURE);
}
}
Then you would pass it in as
malloc_and_check(&pi);
The pointer var is allocated memory dynamically but it is local to the function malloc_and_check. The pointer pi in the function main will not get to know the address of the memory allocated to var. It is a bad access and may also result in crash sometimes.
try the code below to get the expected results :
#include <stdio.h>
#include <stdlib.h>
void malloc_and_check(int **var)
{
int *var1;
if(!(var1 = (int*)malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
exit(EXIT_FAILURE);
}
else
*var = var1;
}
int main(int argc, const char * argv[])
{
int *pi;
malloc_and_check(&pi);
*pi = 5;
printf("%d", *pi);
free(pi);
}
You are trying to pass the pointer by value (pass by value). You need to pass a double pointer to the function malloc_and_check. Due to this the value assigned to the pointer is not reflecting back in the caller.
Please modify your code as below:
#include <stdio.h>
#include <stdlib.h>
void malloc_and_check(int **var)
{
if(!(*var = malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
exit(EXIT_FAILURE);
}
}
int main(int argc, const char * argv[])
{
int *pi;
malloc_and_check(&pi);
*pi = 5;
printf("%d", *pi);
free(pi);
}
The change you make to var in the function is lost when the function returns. Either you need to pass var as a double pointer or you need to return a pointer from the function.
Example where the function returns a pointer:
#include <stdio.h>
#include <stdlib.h>
int* malloc_and_check()
{
int *var;
if(!(var = malloc(sizeof(int))))
{
fprintf(stderr, "Insufficient Memory\n");
exit(EXIT_FAILURE);
}
return var;
}
int main(int argc, const char * argv[])
{
int *pi;
pi = malloc_and_check();
*pi = 5;
printf("%d", *pi);
free(pi);
}

incompatible pointer compiler error

I have this assignment where we expected to write a program that takes
a positive integer number as a command line argument and prints the
smallest prime number bigger than the given number.
The main function shouldn't be edited, however, you may create a
header file for defining needed functions.
So far this is what I came up with, I just can't find out what
is wrong with my program. Help is appreciated.
main function: I can't edit the main function, however, you can create a header
#include "slow-prime.h"
int main(int argc, char *argv[]) {
int num;
int nxt;enter code here
int ret = EXIT_FAILURE;
if (argc < 2) {
printf("error: missing command line argument\n");
goto ERROR;
if (get_number(argv[1], &num)) {
printf("error: %s not a number\n", argv[1]);
goto ERROR;
}
next_prime(num, &nxt);
printf("%d\n", nxt);
ret = EXIT_SUCCESS;
ERROR:
return ret;
}
}
needed functions are created in the slow-prime.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// define true and false
#define true 1
#define false 0
// check whether the numer is prime or mnot
int isPrime(int num){
if (num < 2) {
return false;
}
for (int i = 2; i <= num / i; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
// get number
void get_number(char *argv[], int num) {
num = atoi(argv[1]);
}
// loop through the numbers/ and pick the one
void next_prime(int num, int next){
for(int i = 2; i < 80; i++){
if (isPrime(i) == true){
next = i;
if (next > num) {
return exit(0);
}
}
}
}
Error Message:
error
You have:
void get_number(char *argv[], int num) {
and you are calling the function using:
if (get_number(argv[1], &num)) {
You are passing the wrong types for both arguments.
argv[1] is of type char*.
&num is of type int*.
I think you should to use:
void get_number(char *arg, int *num) {
and change the implementation slightly.
void get_number(char *arg, int *num) {
*num = atoi(arg);
}
Also, given that get_number returns void, you cannot use it in the conditional of an if statement. You'll need to change its return type to something else, an int perhaps. In that case, using atoi might not be appropriate. atoi returns 0 when it cannot convert the string to an int. If 0 a valid value for you, then atoi is not a good choice. However, you can use sprintffor all cases.
If 0 is not a valid number, you can use:
int get_number(char *arg, int *num) {
*num = atoi(arg);
return *num;
}
If 0 is a valid number, you can use:
int get_number(char *arg, int *num) {
return (sprintf(arg, "%d", num) == 1);
}

create thread - passing arguments

I am attempting on creating multiple threads that each thread calculates a prime. I am trying to pass a second argument to a function using thread create. It keeps throwing up errors.
void* compute_prime (void* arg, void* arg2)
{
here is my main() with the create thread. &primeArray[i] after &max_prime is giving me the errors.
for(i=0; i< num_threads; i++)
{
primeArray[i]=0;
printf("creating threads: \n");
pthread_create(&primes[i],NULL, compute_prime, &max_prime, &primeArray[i]);
thread_number = i;
//pthread_create(&primes[i],NULL, compPrime, &max_prime);
}
/* join threads */
for(i=0; i< num_threads; i++)
{
pthread_join(primes[i], NULL);
//pthread_join(primes[i], (void*) &prime);
//pthread_join(primes[i],NULL);
//printf("\nThread %d produced: %d primes\n",i, prime);
printf("\nThread %d produced: %d primes\n",i, primeArray[i]);
sleep(1);
}
the error i get is:
myprime.c: In function âmainâ:
myprime.c:123: warning: passing argument 3 of âpthread_createâ from incompatible pointer type
/usr/include/pthread.h:227: note: expected âvoid * (*)(void *)â but argument is of type âvoid * (*)(void *, void *)â
myprime.c:123: error: too many arguments to function âpthread_createâ
It works fine if i take out the second argument.
You can only pass a single argument to the function that you are calling in the new thread. Create a struct to hold both of the values and send the address of the struct.
#include <pthread.h>
#include <stdlib.h>
typedef struct {
//Or whatever information that you need
int *max_prime;
int *ith_prime;
} compute_prime_struct;
void *compute_prime (void *args) {
compute_prime_struct *actual_args = args;
//...
free(actual_args);
return 0;
}
#define num_threads 10
int main() {
int max_prime = 0;
int primeArray[num_threads];
pthread_t primes[num_threads];
for (int i = 0; i < num_threads; ++i) {
compute_prime_struct *args = malloc(sizeof *args);
args->max_prime = &max_prime;
args->ith_prime = &primeArray[i];
if(pthread_create(&primes[i], NULL, compute_prime, args)) {
free(args);
//goto error_handler;
}
}
return 0;
}
In case of std::thread, the user can pass arguments to the thread function in the following method
std::thread(funcName,arg1,arg2);
for instance,
//for a thread function,
void threadFunction(int x,int y){
std::cout << x << y << std::endl;
}
// u can pass x and y values as below
std::thread mTimerThread;
mTimerThread = std::thread(threadFunction,1,12);
This is the code of Manakarse , everything is really good but you need a
pthread_join(thread[i],NULL)
just to be sure all of threads will successfully execute before end of main thread("main will "waiting" while all of threads aren't finished yet)
;
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
int stop_flag;
char name[30];
} _process_data;
typedef struct
{
int meter_no;
int port_no;
} _process_control;
typedef struct
{
_process_data *process_data;
_process_control *process_control;
} compute_prime_struct;
void *compute_prime (void *args)
{
compute_prime_struct *actual_args = args;
printf("actual_args->process_data->stop_flag [%d]\n",actual_args->process_data->stop_flag);
printf("actual_args->process_data->name [%s]\n",actual_args->process_data->name);
printf("actual_args->process_control->meter_no [%d]\n",actual_args->process_control->meter_no);
printf("actual_args->process_control->port_no [%d]\n",actual_args->process_control->port_no);
free(actual_args);
return 0;
}
void fill_data(_process_data *process_data,_process_control *process_control)
{
process_data->stop_flag=1;
process_data->name[0]='P';
process_control->meter_no=6;
process_control->port_no=22;
pthread_t tid;
compute_prime_struct *args = malloc(sizeof (*args));
args->process_data = malloc(sizeof (*args->process_data));
args->process_control = malloc(sizeof (*args->process_control));
memcpy (args->process_data, process_data, sizeof (args->process_data));
memcpy (args->process_control, process_control, sizeof (*args->process_control));
if(pthread_create(&tid, NULL, compute_prime, args))
{
free(args);
printf("Error here");
}
sleep(1);
}
int main()
{
_process_data process_data;
_process_control process_control;
fill_data(&process_data,&process_control);
return 0;
}

Resources