Pthread struct argument with void* - c

Hy,
I was wondering if something like this is possible, without using heap(malloc/calloc) Suppose I have a struct
like this:
typedef struct {
void* par1_;
void* par2_;
}parameters;
and another one for position:
typedef struct {
short x;
short y;
}position;
This is a function that gets called by the thread.
void* car(void* arg)
{
parameters car_type = *((parameters*) arg);
int first_par = *(int*)&car_type.par1_;
int second_par = *(int*)&car_type.par2_; // can I do this?
//if yes how do I extract now values from position struct "pos.x and pos.y"
}
From my main thread I want to mark position in the struct "position", assign that struct to the second parametar "par2_", and than send that to my function car.
int main()
{
parameters pars;
position pos;
pos.x = 44;
pos.y = 25;
pars.par1_ = (void*) CAR_TYPE; // Global Variable
pars.par2_ = &pos; // not sure about this?
pthread_t tid;
pthread_create(&tid, NULL, car, (void*) &pars);
pthread_join(tid, NULL);
I'm sorry if this is a stupid question. Obviously I'm new to all this. Once again, I do not want to use heap. This is minimal example of my program.

I think you want something more like this;
void* car(void* arg)
{
parameters car_type = *((parameters*) arg);
int first_par = car_type.par1_; // This is CAR_TYPE is it really an int?
position *second_par = (position *)car_type.par2_;
second_par->x, second_par->y;
}
Although you might just want to change your parameters struct to include the types you really want.
typedef struct {
int par1_;
position* par2_;
}parameters;
void* car(void* arg)
{
parameters car_type = *((parameters*) arg);
int first_par = car_type.par1_; // This is CAR_TYPE is it really an int?
car_type.par2_->x; //access like this
}

Not sure what you're asking, so I'll give you standard advice that seems like it pertains to the situation.
Lifetime
Be very careful when passing pointers to stack memory. Always keep these three things in mind:
What will use the pointer?
What will it be used for? Which functions will end up with it? You'll need to know this to deal with the next two points.
Where will the pointer be stored?
If the pointer never leaves the stack, it's fine. If the pointer gets stored in heap memory, which has a chance of outliving the stack frame, alarm bells. If the pointer outlives the stack frame, scary unexpected data corruption is par for the course. Do not allow that to happen.
When will the pointer be used?
Anything in or called by the stack frame in which the memory is first used is OK. Anything above that, and the memory is not yours to play with. Make sure that you never ever EVER EVER EVER return a pointer to stack memory you've just got.
To reiterate:
Do:
#include <stdio.h>
int main(int argc, char *argv[]) {
int nums = {12, 630, 43, 0};
printf("%d", sum(nums));
}
int sum(int *num_pointer) {
int count = 0;
for (; *num_pointer; num_pointer += 1) {
add(&count, *num_pointer);
}
return count;
}
void add(int *a, int b) {
*a += b;
}
Don't:
int main(int argc, char *argv[]) {
print_int(get_int(7));
}
int *get_int(int value) {
return &value;
}
void print_int(int *num) {
printf("%d", *num);
}
Also, don't type-cast when you don't have to. It's a big sign pointing towards bad program design; consider revising it.

Related

C: what is a void* besides a pointer?

Reading CMU's OS Course Home Page, they say:
"It is a good idea to be familiar with C conventions. For example, it is not generally the case that a void * is a pointer. If seeing a void * parameter, or a void ** parameter, in a function prototype would be confusing, this would be a good area to look into."
I honestly have no idea what they mean by this, what is a void * if not a pointer?
One case where void * is not a pointer involves passing data to a callback function. Imagine some library gives you a function which does some useful work, and calls your function (callback) in the middle of that work.
// useful_header.h
int do_useful_work(int data1, int data2, int (*callback)());
You call this function like this:
// your_code.c
int my_callback()
{
...
return 42;
}
int main()
{
int useful_result = do_useful_work(2, 3, my_callback);
}
What if you want to pass data to your callback? The company which provides do_useful_work doesn't know which data your callback wants to get. So it provides the most generic thing - void *. Your callback interprets it as a pointer to your struct.
// useful_header.h
int do_useful_work(int data1, int data2, int (*callback)(void *), void *user_data);
// your_code.c
struct MyData
{
int x, y, z;
};
int my_callback(void *pointer)
{
struct MyData *data = pointer;
...
return data->x + data->y + data->z + 42;
}
int main()
{
struct MyData data = {5, 6, 7};
int useful_result = do_useful_work(2, 3, my_callback, &data);
}
This has an edge-case: what if your callback wants to receive only a small item (of type int), and not a whole struct? Then you could interpret the pointer as int.
// your_code.c
int my_callback(void *not_really_pointer)
{
int data = (int)not_really_pointer;
...
return data + 42;
}
int main()
{
int useful_result = do_useful_work(2, 3, my_callback, (void *)5);
}
Here, the void * argument is not really a pointer - it's a number, which is passed using void * type because C enforces type-checking.
Having said that, this is an example of sloppy coding; making a struct with one element would be clearer here.

C: Passing variable down the functions, is this design valid?

This question may appear too basic, but please do look at it:
#include <stdio.h>
void f3(int *p) {
*p = 100;
}
void f2(int *p) {
f3(p);
}
void f1(int *p) {
f2(p);
}
int main(int argc, char **argv) {
int a;
f1(&a);
printf("%d\n", a);
return 0;
}
Basically, the address of a stack variable (a) is passed to multiple functions down the call stack where its value is changed at the last function.
Is this way of changing values a good design? If not, what should be a better design?
My question arises because with a Heap variable (say a being a heap variable as shown below), this design is OK since the allocated memory is "global" to all functions.
int main(int argc, char **argv) {
int *a = malloc(sizeof(int)*1);
f1(a);
printf("%d\n", a);
free(a)
return 0;
}
But with a local variable, I'm doubtful if 2 levels down the call stack, its still valid to access the memory with just a single level pointer.
Should I pass another level of pointer down each function call? (like f1(&a) then f2(&p) and so on).
What you are doing is absolutely correct. The variable a exists all the time, and f3 will receive the address of variable a. No problem at all.

How do I bind arguments to a C function pointer?

I have done some research about how to use function pointers in C and I was trying to do some model of an object-oriented kind of thing. So to model such a thing I have been told I would have to add function pointers to the structs, so that they would be kind of 'an object'.
As I am pretty new on programming in C, this question may seem a little stupid (or very easy to answer), but on the Internet, I just found examples concerning C++ and that's not what I am searching.
Here is an example I would like to show, so that you can easily understand what my question is about:
try.h-file:
struct thing {
void (*a)(int, int);
};
void add(int x, int y);
try.c-file:
#include <stdio.h>
#include <stdlib.h>
#include "try.h"
void add(int x, int y) {
printf("x + y = %d\n", x+y);
}
int main(int argc, char* argv[]) {
struct thing *p = (struct thing*) malloc(sizeof(struct thing));
p->a = &add;
(*p->a)(2, 3);
free(p);
p = NULL;
return 0;
}
As an example I would want to have always x = 2, so the function pointer in struct thing would be this kind of pointer: void (*a)(int) and not void (*a)(int, int) anymore.
How can I bind the argument x = 2 when passing the function pointer to the struct (line p->a = &add;)? Is this even possible in C? In C++ I have seen something like std::bind, but I wasn't able to do this in C.
The function pointer has to have the same signature (type and arguments) as the function it points to, so you can't really do it like that.
You could wrap the bind and the call in another couple of functions:
struct thing {
void (*a)(int, int);
int x;
};
...
void bind1st( struct thing *p, int arg )
{
p->x = arg;
}
void call( struct thing *p, int arg )
{
p->a( p->x, arg );
}
You'll want to experiment with this a bit, but that should get you started.
I've had similar problems,and I used the following method to resolve, use gcc to compile it work, use clang to compile it do not work.
#include <stdio.h>
typedef int (*add_t) (int);
add_t add2(int x) {
int add1(int y) {
return x + y;
}
return add1;
}
int main() {
//add2(2);
printf("%d\n", add2(2)(3));
}
A way that no one have talked about yet is to use some JIT logic (I won't provide a working example right now, because I've not yet tried it, but I will use it at some time for a RPC library). This is not strictly speaking a C language feature, and it's feasible only on CPU/MCU architecture where you can write to an executable memory segment (it's possible on x86_64, x86, some ARMs etc.).
The principle is really just to construct a function dynamically that will call the wrapped function in a similar way python defines dynamically nested functions.
Some library you can use for it : libgccjit, libjit, gnu-ligthning, llvm etc.
I think this is the best solution .
typedef void(*call_type)();
call_type bind(void (*f)(int,int), int a, int b) {
void call() {
f(a,b);
}
return &call;
}
void f(int a, int b){
printf("%d, %d", a, b);
}
int main(){
call_type c = bind(f, 5, 4);
c();
}

Threads and parallel programming

Say I want to compute the product of n complex numbers.
What I'm trying to do is that compute the product of the 2*i and 2*i+1 (i=0;i<n/2) complex numbers in threads. ie, clump 2 numbers together and compute their product, therefore I shall get n/2 products. Then again perform the same action on these n/2 products. So on and so forth, and carry on till the value of n is 1.
Here's my code
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct complex{
int a;
int b;
};
struct complex arr[1000];
struct arg {
struct complex arr1;
struct complex arr2;
int i;
};
//struct arg *argv;
struct arg *argv=malloc(sizeof(struct arg));
void *multiplier(struct arg *argv)
{
int real,imaginary;
real=(argv->arr1.a)*(argv->arr2.a)-(argv->arr1.b)*(argv->arr2.b);
imaginary=(argv->arr1.a)*(argv->arr2.b)+(argv->arr1.b)*(argv->arr2.a);
arr[argv->i].a=real;
arr[argv->i].b=imaginary;
printf("real=%d imaginary=%d no=%d\n",real,imaginary,argv->i);
pthread_exit(0);
}
int main(void)
{
int n,i,j,flag=0,q;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d + i%d",&arr[i].a,&arr[i].b);
for(i=0;i<n;i++)
printf("%d + i%d\n",arr[i].a,arr[i].b);
while(n!=0)
{
if(n%2==1)
flag=1;
else
flag=0;
for(i=0;i<n/2;i++)
{
argv->arr1.a=arr[2*i].a; /* SEG FAULT HERE */
argv->arr1.a=arr[2*i].b;
argv->arr2.a=arr[2*i+1].a;
argv->arr2.a=arr[2*i+1].b;
argv->i=i;
pthread_create(&tid,&attr,multiplier,(void *) argv);
}
pthread_join(tid,NULL);
if(flag==1)
{
arr[n/2].a=arr[n-1].a;
arr[n/2].b=arr[n-1].b;
}
n=n/2;
}
return(0);
}
However my code gives me seg fault at line 45. I've been trying to figure out what's wrong with it but to no avail. I probably might be making a fundamentally horrendous error, but do help me out.
EDIT 1:
Probably the most stupid error ever.
I can't allocate memory globally like the way I just did.
I just inserted the Malloc into the main function and the program works.
Each thread needs it's own memory passed in via argv to not overwrite the other thread data.
So you might liek to move this line
struct arg * argv = malloc(sizeof(struct arg));
to here:
for(i = 0; i < n/2; ++i)
{
struct arg * argv = malloc(sizeof(*argv));
argv->arr1.a = arr[2*i].a;
Also checking the result of the calls malloc() might not be a bad idea.
Then let the thread function free() its memory when its done with it:
void * multiplier(struct arg * argv)
{
...
free(argv);
pthread_exit(0);
}
Also the thread function to be passed to pthread_create()is defined as:
void *(*)(void *)
So you shall declare yours this way:
void * multiplier(void * pvargv)
{
struct arg * argv = pvargv;
...
It's pretty hard to figure out which of your lines is line 45.
Also, this looks very wrong:
struct arg *argv=malloc(5*sizeof(struct complex));
It's very rarely correct to mis-match types like that, and struct complex looks nothing like struct arg, so this really seems strange. Also, you shouldn't have a global named argv while u
First, I'm not sure if the memory size you allocate for argv is sane enough. Second, you modify this argv thing, create a thread and immediately overwrite it, probably, before the thread even gets its hands on it.

Getting error when modifying MyType constructed using typedef in C

I create a type and try to change the int value in it.
But it keeps printing 240.
I don't know why, can anyone help me?
Here is my code:
typedef struct{
int i;
}MyType;
do(MyType mt, int ii){
mt.i = ii;
}
int main(int argc, char ** argv){
MyType mt;
do(mt, 5);
print("%d\n", mt.i);
}
Passing mt by value to function do(). Any changes made will be local to the function. Pass the address of mt:
void do_func(MtType* mt, int ii){
mt->i = ii;
}
MyType mt;
do_func(&mt, 5);
So first, your do function has some problems. You have failed to specify a return type, so int is assumed (pre-C99), but I see no reason to not just specify it. Second, do is a reserved keyword in C.
You are passing your struct by value, so a copy is made, passed to your do function, and that is modified. Everything is passed by value in C, period. Your mt variable declared in main is never touched.
Take a MyType* in your code if you need to modify one or more of its member variables, take a MyType** if you need to allocate memory for the structure itself (i.e., initialize a pointer).
// pass a pointer to the function to allow
// for changes to the member variables to be
// visible to callers of your code.
void init_mytype(MyType *mt, int ii){
if(mt)
mt->i = ii;
}
MyType mt;
init_mytype(&mt, 1);
// pass a pointer to pointer to initialize memory
// for the structure and return a valid pointer.
// remember, everything is passed by value (copy)
void init_mytype(MyType **mt, int ii) {
if(mt) {
*mt = malloc(sizeof(MyType));
if(*mt)
(*mt)->i = ii;
}
}
MyType *pmt;
init_mytype(&pmt, 1);

Resources