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

Accessing struct pointer as pthread arg causes seg fault?

所以这是我的一小部分代码。本质上我是从一个方法启动另一个线程,但是当我将整数传递给 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");

create_new_room 中的 r_index 变量是函数的局部变量。然后将它的地址传递给 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);