将结构指针作为 pthread arg 访问会导致段错误?

时间:2021-03-19 16:45:17

标签: c arguments pthreads

这里是我代码的一小部分。本质上,我是从一个方法开始另一个线程,但是当我将整数传递给 pthread 时,我无法访问结构成员,就像在调用线程之前只能访问两行一样。自从我传递这个参数并运行一个新线程后发生了什么?

请注意,我的程序总是在 printf("1\n"); 之后立即崩溃,当我意识到 FD_ZERO 不起作用时,我发现了这个错误。

结构定义(在全局区域):

typedef struct {
        fd_set read_set, write_set;
        unsigned int room_id;
        char room_name[16];
} room;

调用方方法:

void create_new_room(int cli_index, char buffer[]) {

        pthread_mutex_lock(&mutex);

        char room_name[16], password[16];
        int capacity, r_index;

        room *new_room = malloc(sizeof(room));

        pthread_t tid;

        FILE *room_file = NULL;

        if((room_file = fopen("room-info.txt", "a")) == NULL) {
                perror("Failed to open file.");
                exit(-1);
        }

        // Split command data into separate strings ready to assign as room struct members
        strtok(buffer, " ");
        strcpy(room_name, strtok(NULL, " "));
        capacity = atoi(strtok(NULL, " "));
        strcpy(password, strtok(NULL, " "));

        // Initialise room struct
        // --Zero write set
        FD_ZERO(&(new_room->write_set));
        // --Set room name
        strcpy(new_room->room_name, room_name);
        // --Set room id
        new_room->room_id = ++natural_id;
        // --Add room to room_list[] and get its index in the array
        for(r_index = 0; r_index < 10000; ++r_index) {
                if(!room_list[r_index]) {
                        room_list[r_index] = new_room;
                        break;
                }
        }

        // Write data to file
        fprintf(room_file, "%s\n", room_name);
        fprintf(room_file, "id=%u\n", natural_id);
        fprintf(room_file, "owner=%s\n", client_list[cli_index]->name);
        fprintf(room_file, "capacity=%d\n", capacity);

        fclose(room_file);

        printf("about to test\n");
        printf("Testing room struct:\n");
        printf("--room name = %s\n", room_list[r_index]->room_name);
        printf("--room id = %u\n", room_list[r_index]->room_id);
        printf("post-test.....................\n");

        // Run new thread as active room
        printf("Starting new room: %s\n", room_name);
        pthread_create(&tid, NULL, (void *) &active_room, &r_index);

        pthread_mutex_unlock(&mutex);


}

开始新的 pthread 方法:

void active_room(void *index) {

        char storage_buffer[BSIZE], output_buffer[BSIZE+32];

        struct timeval timeout;

        int r_index = *(int *) index;

        while(1) {

                // debugging lines.
                printf("1\n");
                printf("room name: %s\n", room_list[r_index]->room_name);
                printf("room id: %u\n", room_list[r_index]->room_id);
                FD_ZERO(&(room_list[r_index]->read_set));
                read_set = write_set;

                timeout.tv_sec = 5;

                printf("2\n");

1 个答案:

答案 0 :(得分:1)

r_index 中的 create_new_room 变量是函数的局部变量。然后将其地址传递给 pthread_create 以便线程可以使用它,但随后 create_new_room 退出,导致 r_index 的生命周期结束。然后,当线程尝试取消引用其参数时,它指向的内存不再有效,从而触发 undefined behavior

您需要为线程的参数动态分配内存,以便它在 create_new_room 退出后继续存在:

int *r_index_arg = malloc(sizeof *r_index_arg);
*r_index_arg = r_index;
pthread_create(&tid, NULL, (void *) &active_room, r_index_arg);

然后你需要确保你free线程中的内存:

int r_index = *(int *) index;
free(index);
相关问题