0
votes

I'm trying to edit this code to work with ints parameters:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <string.h> 


void* worker (void* param) {
      int* nr = (int *) param;
  printf ("I got: %d\n",nr);
}

int main (int argc, int *argv[])
{
  pthread_t th;
  int i;  
  for(i=1;i<argc;i++){
      pthread_create (&th, NULL, worker,(void*)argv[i]);
      pthread_join (th, NULL);
  }
}

This is not working, smth about pointers, I don't understand. Can anyone explain me? I don't want to use "atoi" function. For number 5 and 2 I get: -1078000975,-1078000973 and a warning:

11:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=] printf ("I got: %d\n", nr); ^

3
int nr = *(int *)paramuser1551592
the code is overlaying the value in 'th' for every thread created, so the pthread_join will only see the last thread created, not all the threadsuser3629249

3 Answers

0
votes

A few issues:

  1. argv should be written char * argv[], not int * argv[].

  2. Your (void *) cast in your pthread_create() call is unnecessary.

  3. Your thread function should return a void *.

  4. atoi(), or its more capable cousin, strtol(), is exactly what you're looking for, here. You can either use them, or convert your strings manually, which is suboptimal.

Here's a working version:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

void * worker (void * param)
{
    char * numstr = param, * endptr;

    long num = strtol(numstr, &endptr, 0);
    if ( *endptr ) {
        printf("Invalid number.\n");
    }
    else {
        printf ("I got: %ld\n", num);
    }

    return NULL;
}

int main (int argc, char *argv[])
{
    pthread_t th;
    for ( int i = 1; i < argc; ++i ) {
        pthread_create (&th, NULL, worker, argv[i]);
        pthread_join (th, NULL);
    }
    return 0;
}

and some sample output:

paul@horus:~/src/sandbox$ ./trd 5 haha 10
I got: 5
Invalid number.
I got: 10
paul@horus:~/src/sandbox$
0
votes

If the arguments you recieve are smaller than 10, you can do this:

pthread_create (&th, NULL, worker,(void*)(argv[i][0]-'0'));

This can be done because ASCII numbers begin at 48 ('0' value). So if you receive a '7' (55 ascii number), you can subtract the '0' to get it: 55-48=7. If the arguments can be 10 or greater, you must use atoi or a self-implementation of that function, as you can not cast from char* to int in C.

There is another problem with your code, you try to print an int*, which is only a variable that contains a memory address. You should recieve it as an int:

void* worker (void* param)
{
  int nr = (int) param;
  printf ("I got: %d\n",nr);
}

EDIT: So your code should look like this:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <string.h> 


void* worker (void* param) {
      int nr = (int) param;
  printf ("I got: %d\n",nr);
}

int main (int argc, char *argv[])
{
  pthread_t th;
  int i;  
  for(i=1;i<argc;i++){
      pthread_create (&th, NULL, worker,(void*)(argv[i][0]-'0'));
      pthread_join (th, NULL);
  }
}

It works for me...

0
votes

You should pass the pointer to the string and then manipulate it.

pthread_create (&th, NULL, worker, argv[i]);   //cast is not required

void* worker (void* param) {
      char* nr = param ;

Now you got your string in the thread. Get the first character, and convert it to an integer.

    int n = nr[0]-'0' ;
    printf ("I got: %d\n",n);
}