Posix Pthread in C - c

I have the following questions regarding pthread of posix.
When we receive data in pthread_join() returned by the function being executed by a thread, we type cast the variable like (void **) even though the variable is a single pointer.
int *x;
pthread_join(tid,(void**)&x);
printf("%d",*x);
Should I derefrence the type casted argument (in case of structure)? Why can't I do like
struct Data *obj= & (struct Data*)arg;?
int main()
{
...
pthread_create(tid,NULL,Foo,&obj);
...
}
void *Foo(void *arg)
{
struct Data *obj=* (struct Data*)arg;
}
How does pthread_join() internally receives the returned variable.
Regards

First of, you should never do (void**)&x as pointers off different types need not be of the same size.
Now, some scenarios (some valid, some working but invalid and some just broken):
Foo() returning a pointer to an int (valid):
void* Foo(void *arg)
{
int *ret = malloc(sizeof(int));
*ret = 42;
return ret;
}
void *ptr;
int *x;
pthread_join(thread, &ptr);
x = ptr;
printf("%d", *x);
free(x);
Foo() returning an int (invalid but usually work):
Platforms where int is larger than a pointer this will not work.
void* Foo(void *arg)
{
return 42;
}
void *ptr;
int x;
pthread_join(thread, &ptr);
printf("%d", (int)ptr);
Foo() returning a pointer to static int (invalid and never works):
All static memory in Foo() is freed when Foo() returns, before pthread_join() can copy the value.
void* Foo(void *arg)
{
int ret = 42;
return &ret;
}
void *ptr;
int *x;
pthread_join(thread, &ptr);
x = ptr;
printf("%d", *x);

You shouldn't do that: at your level of understanding of C casts should be simply forbidden.
If you learned that in a course, this is not really high quality.
First of all, &x is the address of a pointer so the result is int**, so well two indirections.
But casting that int away is dangerous, pointers to int and void don't have necessarily the same width on different platforms. So please do
void*x;
pthread_join(tid, &x);
printf("%d",*(int*)x);

Related

Returning pointers back to itself

My coding assignments came with it's header file, meaning we need to use the same data types, and not vary anything.
There is a lot of pointers, (mainly a lot of void *). Meaning things are confusing, more than difficult.
we have to do a separate function, just to increment the value referenced by a pointer. But given the nature of program, I don't want to constantly make new pointers.
The code is as follows:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int a;
a=atoi(str);
return &a;
}
void *intal_increment(void *intal)
{
int *a= (int *)intal;//new pointer;
++*a;
//value referenced has been incremented;
*(int *)intal=*a;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char *dummy;
gets(dummy);
x=(int *)intal_create(dummy);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
}
I wanted x to be the parameter called, and also for it to store the return value. The printf address is merely for my understanding.
The segmentation faults never end, and from my understanding, I'm just returning a pointer and asking a pointer to stop the return pointer
By incorporating all the comments. Mainly allocating memory to dummy before passing it gets() function and allocating memory in heap for the return pointer of intal_create.These two fixes solve the issue. Have a look at the following code for reference.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int *a = (int *)malloc(sizeof(int));
*a = atoi(str);
return a;
}
void *intal_increment(void *intal)
{
//Here i am not allocating
int *a = (int *)intal;//new pointer;
(*a)++;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char dummy[20] = {0};
fgets(dummy,5,stdin);
x = (int *)intal_create(dummy);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void*)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void *)x);
//Make sure you deallocate the memory allocated in the intal_create function.
free(x);
}

Returning a value from a thread in C

Hello i am having a hard time understanding how a value is returned from a thread in c. I have this working example:
#define NTHREADS 4
void *neg (void * param) {
int *l;
l=(int *) param;
int *r=(int *)malloc(sizeof(int));
*r=-*l;
return ((void *) r);
}
int main (int argc, char *argv[]) {
pthread_t threads[NTHREADS];
int arg[NTHREADS];
int err;
for(long i=0;i<NTHREADS;i++) {
arg[i]=i;
err=pthread_create(&(threads[i]),NULL,&neg,(void *) &(arg[i]));
if(err!=0)
error(err,"pthread_create");
}
for(int i=0;i<NTHREADS;i++) {
int *r;
err=pthread_join(threads[i],(void **)&r);
printf("Resultat[%d]=%d\n",i,*r);
free(r);
if(err!=0)
error(err,"pthread_join");
}
return(EXIT_SUCCESS);
}
What i find hard to understand is the following:
the function neg returns a pointer * r casted in (void *) pointing to a value in the heap. Thus returning an adress to the heap basically. Then in pthread_join we get that return value by doing &r (which by itself seems illogical? grab the adress of an adress?) then casting to a pointer of a pointer? Why do we do that?
Thanks for the help!
Consider this code, which is perfectly valid and prints "5 5 5 5".
int x = 5;
int *p = &x;
int **pp = &p;
int ***ppp = &pp;
printf("%d %d %d %d\n", x, *p, **pp, ***ppp);
return 0;
C allows you to have any depth of pointers, initialized with a corresponding number of address-of operators. In your example, you allocated an int * and the function must return a void **, so you have to dereference the result twice and cast it, which you accomplished by casting the int *.
So,"grab the adress of an adress?" Yup! Well, the address of a pointer, which may hold the address of an int, or another pointer.
Then in pthread_join we get that return value by doing &r (which by
itself seems illogical? grab the adress of an adress?) then casting to
a pointer of a pointer? Why do we do that?
First thing you need to understand is that the thread function(s) do not return the value directly; they send the value to the pthreads library using pthread_exit() or returning a value (as in your example) and
it's retrieved with a call to pthread_join() (by using the thread identifier). Since the return value is a pointer, you have to
pass a pointer to pointer to retrieve it from pthread_join() function.
For the understanding purposes, consider this pseudo code:
/* thread */
void *neg(void *arg)
{
return ptr; // let's say "ptr" is stored in the library as "retval_thread_id"
}
int pthread_joing(pthread_t thread_id, void **retval)
{
*retval = retval_thread_id;
}
int main(void)
{
rc = pthread_join(threads[i],(void **)&r);
}
So, how can you retrieve the pointer retval_thread_id from pthread_join() without using a pointer to pointer?
This is nothing different than passing a ptr-to-ptr to a function and the function stores at the pointee of the passed pointer:
void func(int **p)
{
*p = malloc(10 * sizeof *p);
}
int main(void)
{
int *p;
func(&p);
}
By the way , all the casts you do (except the one in the call to pthread_join() -- You wouldn't this either if you declared r as void *r;.) are unnecessary. A void pointer can be assigned to any other data pointer in C without a cast.

Generic pointer to pointer

I understand that according to standard void * is generic pointer, and void ** is not. So, in my program, I am trying to cast void * and not directly type cast void ** but I am not getting expected results. I think I am missing something very basic in here.
#include <stdio.h>
void check(void **p)
{
printf("value: %d\n", *(int *)*p);
}
int main()
{
int a[] = {6,2,5,1,8};
int *p;
p = a;
void **val;
val = (void *)p;
check(val);
return 0;
}
I have a void ** pointer val, which is pointing to int * but casted to void *. I pass this to function check, which is expecting void **. In my printf, I first cast *p (which is void *) to int * and then derefernce it. I get some random value. Am I missing something here?
The problem is in the call to printf:
printf("value: %d\n", *(int *)*p);
In main, val (which is a void **) contains the contents of a int *. This is then passed to check, where is now called p. This needs to be casted to an int * to read correctly:
printf("value: %d\n", *(int *)p);
Of course, since a void ** is not a generic pointer, it doesn't make much sense to do this. Best to get rid of the extra level of indirection which isn't being used anyway:
void check(void *p)
{
printf("value: %d\n", *(int *)p);
}
int main()
{
int a[] = {6,2,5,1,8};
int *p;
p = a;
void *val;
val = p;
check(val);
return 0;
}
Change val = &p; to val = p;
Probably it was a kind of "typo" since you had already passed the value once correctly and later also dereferenced it.
EDIT:
You can change: val = (void *)p; to val = (void *)&p;
As you said yourself, void** is not a generic pointer. It is a pointer that point to an object of type void*, and nothing else. Using a cast to point it at an object of type int* is type punning.
In your case, you should simply cast your int* to void*, and back to int* again. No void** involved.

How to store int pointer in void*?

Scenario is as follows:
typedef struct a {
void* val;
} a_t;
void fun (void** val)
{
int a = 5;
*val = &a;
}
a_t *x;
x = malloc (sizeof *x);
fun (&x->val);
printf ("%d", *((int*)(x->val)));
I would expect, that the x->val is of type void* (when used in printf()). How can I get back that int value I stored into it?
The problem is in fun
If you expect 5 on STDOUT than this function should look like this:
void fun (void** val)
{
int *a = malloc(sizeof(int));
*a = 5;
*val = a;
}
You should not return pointer to automatic variable because it's allocated on stack and deferred after function executions. To get more info look at this answer
The problem is that the pointer is set to a local variable. So when the function terminates, it's memory will be de-allocated, thus the pointer will be set to garbage (it will become a dangling pointer as Hans suggested).
So if you are lucky, the printf() will print garbage, if not, then it will print 5.
A quick fix would be to add the static keyword to int a, which make it not to be de-allocated when the function gets terminated.
void fun(void** val) {
static int a = 5;
*val = &a;
}
However this is not very flexible, because all the instances of fun() will have the same variable a.
Or you could dynamically allocate memory like this:
void fun(void** val) {
int *a = malloc(sizeof(int));
*a = 5;
*val = a;
}
Don't forget to free your memory like this:
a_t *x;
x = malloc (sizeof *x);
fun (&x->val);
printf ("%d", *((int*)(x->val)));
free(x->val); // this has to go first
free(x);
return 0;
}

Pointer question

Okay I go through 2 layers of functions fun1 calls func2 calls func3 . I pass a pointer all the way down using basically int *ptr, at the lowest "level" of the call stack I also have another function that dynamically allocates memory for an int array. At the top level (func1 level) I always get null back for the passed pointer. I have traced down to func3 and the allocated memory is being filled with values, but as the call stack unwinds func3 -> func2 suddenly the pointer just goes away (0x0000_0000)? I don't understand at func3 level I basically say ptr = allocate_ptr_array, but from that return it goes to NULL! Even though I didn't free the memory, what in the world is going on? I know my question is confusing. I have watched this happen in the debugger though
The pointer is basically passed by value. You need to pass pointer to pointer (int **p) to get the memory allocated back in outer function.
function1(int *p)
{
p = //allocate memory using malloc
}
function2(int **p)
{
*p = //allocate memory using malloc
}
function3()
{
int *p;
function1(p);
// in this case pointer is passed by value.
//The memory allocated will not be available in p after the function call function1.
int **p;
function2(&p);
//in this case pointer to pointer p has been passed.
// P will have the memory allocated even after
//the function call function1
}
}
To illuminate aJ's (completely correct) answer with some code:
void func1(void)
{
int *int_array;
func2(&int_array);
/* Some stuff using int_array[0] etc */
/* ... */
free(int_array);
}
void func2(int **a)
{
/* ... stuff ... */
func3(a);
/* .... stuff ... */
}
void func3(int **a)
{
(*a) = malloc(N * sizeof **a);
}
Here is a good example for future reference bye other people. It makes sense after implementation and thanks to these guys.
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
void func3(int **ptr)
{
int i;
(*ptr) = (int *)malloc(25*sizeof(int));
for (i=0; i < 25; i++) (**ptr) = i;
printf("func3: %d\n",ptr);
}
void func2(int **ptr)
{
func3(ptr);
printf("func2: %d\n", ptr);
}
void func1(void)
{
int *ptr;
printf("ptr before: %d\n", ptr);
func2(&ptr);
printf("ptr after: %d\n", ptr);
}
void func4(int **ptr)
{
static int stuff[25];
printf("stuff: %d\n",stuff);
*ptr = stuff;
}
int main(void)
{
int *painter;
func1();
func4(&painter);
printf("painter: %d\n", painter);
return 0;
}

Resources