1

I create 2 threads, and main() will pass argc and argv to thread, so I use struct arg that contains argc and argv.

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct arg {
   int argc;
   char id[9];
   char **argv;
};

int test1(struct arg *a) {
    int argc;
    char **argv;
    argc = a->argc;
    argv = a->argv;

    if (argc > 3) {
        printf("arg 1 is %s, arg 2 is %s arg 3 is %s\n\n", *(argv+1), *(argv+2),a->id);
    }
    else {
        exit(0);
    }


    return 0;
}
int main(int argc, const char *argv[]) {
    int i;
    void *ret;
    struct arg *a = (struct arg *) malloc(sizeof(struct arg *) * atoi(argv[3]));
    pthread_t *thread = (pthread_t *) malloc(sizeof(*thread) * atoi(argv[3]));

    for(i = 0; i < atoi(argv[3]); ++i) {
        a[i].argc = argc;
        a[i].argv  = argv;
        sprintf(a[i].id,"%d",i);
        pthread_create( &thread[i], NULL , test1 ,(struct arg *)&(a[i]));
    }

    for(i = 0; i < atoi(argv[3]); ++i) {
         pthread_join( thread[i], &ret);
    }

    return 0;
}

I exec my program:

./test 1 2 2

The output looks like:

arg 1 is 1, arg 2 is 2 arg 3 is 0

arg 1 is , arg 2 is  arg 3 is 1

In thread 1 the argv is correct, but in thread 2 the argv address is different than before.

I use gdb to print a->argv address

  • in main argv address is 0x7fffffffdee8
  • in thread 1 argv address is 0x7fffffffdee8
  • in thread 2 argv address is 0x7ffff6fef700

[Switching to Thread 0x7ffff6fef700 (LWP 19472)]

argv address is the same as thread address

I check arg[1]->argv before pthread_create

the address is 0x7fffffffdee8.

Will pthread_create change the address?

Is there something I'm missing?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Tom
  • 99
  • 2
  • 6
  • You should convert `argv[3]` to an integer once (and check that it was not zero, negative, or too big) rather than converting each time you need that number. – Jonathan Leffler Aug 26 '16 at 04:26

2 Answers2

4

This line

struct arg *a = (struct arg *) malloc(sizeof(struct arg *) * atoi(argv[3]));

doesn't allocate the right amount of memory. It should be sizeof(struct arg). You're allocating an array of n structures, so you need the size of the structure itself, not a pointer to it.

I had to clean up a lot of stuff to get this to compile. You should turn on warnings in your compiler and fix them.

Andy Schweig
  • 6,597
  • 2
  • 16
  • 22
3

In this line, you are allocating too little space:

struct arg *a = (struct arg *) malloc(sizeof(struct arg *) * atoi(argv[3]));

It should be more like:

struct arg *a = (struct arg *) malloc(sizeof(*a) * atoi(argv[3]));

You shouldn't tamper with the definition of main(); the const is not part of its type (see What should main() return in C and C++, which also covers the arguments as well as the return value).

You should also make your thread function conform to void *test1(void *vp); that's the type of a thread function. For example:

static void *test1(void *vp)
{
    struct arg *a = vp;
    int argc = a->argc;
    char **argv = a->argv;
    …

The cast in the pthread_create() call is unwarranted.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278