传递指向pthread函数的指针会导致其结构丢失

时间:2015-08-04 03:24:59

标签: c multithreading pointers segmentation-fault pthreads

我正在尝试启动一个线程并给他一个指向结构的指针。但是函数接收的指针不正确。我有一块结构正确但其他人没有。

这是线程启动的功能:

void start_pointer(struct fsm_pointer *pointer) {
    if ( pointer->started != 0 ){
        printf("CRITICAL : A pointer must be started only once");
        return;
    }
    pthread_create(&pointer->thread, NULL, &pointer_loop, (void *)pointer);
    pointer->started = 1;
}

这里是pointer_loop函数:

void *pointer_loop(void * _pointer) {
    struct fsm_pointer * pointer = _pointer; // cast void pointer
    struct fsm_context init_context = {
        .event = event,
        .fnct_args = step.args,
    };
    // call pointer structure member => SEGFAULT
    pointer->current_step.fnct(&init_context); 
    return NULL;
}

结构定义如下:

struct fsm_pointer{
    pthread_t thread;
    pthread_mutex_t mutex_event;
    pthread_cond_t cond_event;
    struct fsm_event input_event;
    struct fsm_step current_step;
    unsigned short started;
};

struct fsm_step{
    void (*fnct)(const struct fsm_context *);
    void * args;
    struct fsm_trans transition;
};

:: EDIT ::
以下是pointerstep结构生效的地方:

struct fsm_pointer * create_pointer(struct fsm_step first_step)
{
    struct fsm_pointer *pointer = malloc(sizeof(pointer));
    pointer->thread = 0;
    pointer->mutex_event = PTHREAD_MUTEX_INITIALIZER;
    pointer->cond_event = PTHREAD_COND_INITIALIZER;
    pointer->input_event = _NONE_EVENT;
    pointer->current_step = first_step;
    pointer->started = 0;
    return pointer;
}

struct fsm_step create_step(void (*fnct)(const struct fsm_context *), void *args)
{
    struct fsm_step result = {
            .fnct = fnct,
            .args = args,
            .transition = TRANS_ENDPOINT,
    };
    return result;
}

以下是管理它的功能:

void test_new_fsm(){
    struct fsm_step step_0 = create_step(&callback, NULL);
    struct fsm_pointer *fsm = create_pointer(step_0);

    start_pointer(fsm);
    sleep(5);
    pthread_join(fsm->thread, NULL);
    sleep(1);
    free(fsm);
}

回调函数仅用于测试:

void callback(const struct fsm_context *context) {
    printf("Callback : event uid : %d \n", context->event.uid);
}

:: / EDIT ::

当我在segfault之前使用调试器(gdb)时,我可以看到指针的地址是正确的(与创建线程之前相同)并且started变量被正确设置为1.但是fnct指针是 NULL ,它会产生段错误。

当在创建线程之前执行与pointer_loop中完全相同的代码(具有正确的变量名称)时,没有任何问题。

那么,是否有人知道会发生什么,或者这只是一个明显的错误,显而易见,超过一天的调试是不够的?

感谢。

2 个答案:

答案 0 :(得分:2)

struct fsm_pointer *pointer = malloc(sizeof(pointer));

应该是:

struct fsm_pointer *pointer = malloc(sizeof(struct fsm_pointer));

struct fsm_pointer *pointer = malloc(sizeof(*pointer));

答案 1 :(得分:0)

您还没有显示struct fsm_pointer所指向的pointer类型的对象存在的代码,但可能是它正在被修改,或者它的生命周期结束,而没有与新创建的线程对它的访问权限。除非您在线程启动函数和调用者中有同步,否则为了排除并发访问/生命周期结束,您必须等到加入线程以释放此结构或以其他方式允许其生命周期结束。