pthread_mutex_init上的分段错误

时间:2014-01-28 19:16:35

标签: c segmentation-fault pthreads

我正在尝试使用线程池作为worker来构建TCP / IP侦听器。 基本的东西不起作用,(cond_wait / cond_signal麻烦)所以我缩小了问题。但是随后的代码我得到了一个分段错误。

struct worker {
    pthread_t      tid;
    pthread_cond_t worker_cv;
    pthread_mutex_t worker_mutex;
    int worker_flag;
};

typedef struct worker worker_t; 

void initialize_flag( worker_t * w)
{
    printf( "Mutex (%d)\n", (int) sizeof w->worker_mutex );
    pthread_mutex_init (& w->worker_mutex, NULL);
    printf( "Cond (%d)\n", (int) sizeof w->worker_cv );
    pthread_cond_init (& w->worker_cv, NULL);
    printf( "Flag\n" );
    w->worker_flag = 0;
}

SF发生在“Mutex”的printf之后。 我传递给initialize_flag()的指针是全局的,并且在main()中被malloc化,以模仿我正在寻找的真实行为。

TIA ((编辑:取自@marcelo的回答): 以下是您要求的相关代码部分

worker_t * worker;

main( )
{
    worker = malloc( sizeof( worker_t ) );

    if ( worker == NULL ) {
        fprintf( stderr, "malloc\n" );
        exit(1);
    }

    fprintf( stdout, "Zero\n" );

    memset( & worker, 0, sizeof( worker_t ) );

    fprintf( stdout, "Init\n" );

    initialize_flag( worker );

3 个答案:

答案 0 :(得分:2)

我看不出代码有什么问题,所以我想这可能是因为w->worker没有将内存块指向pthread_mutex_t的大小。

您没有显示initialize_flag的调用方式,但它应该类似于:

worker_t * w;
w = malloc(sizeof worker_t);
...
initialize_flag(w);

你说你已经在main()分配了这一切。我可以建议您这样做:

worker_t test;
initialize_flag(&test);

看看是否有段错误?最好不要在main()中做任何其他事情。

另外,我建议您在调试器中运行并打印w->worker_mutex,或者创建函数的第一行:

printf( "Mutex (%d:%p)\n", (int) sizeof w->worker_mutex, &(w->worker_mutex) );

答案 1 :(得分:1)

memset( & worker, 0, sizeof( worker_t ) ); // zero worker

不是

相同
memset( worker, 0, sizeof( worker_t ) ); // zero the objected worker designates

您的memset来电正在调用worker之前立即将NULL设为initialize_flag

根本不需要动态分配,只需静态分配worker,它最初会归零:

worker_t worker;

int main(void)
{
    fprintf( stdout, "Init\n" );
    initialize_flag( &worker );

答案 2 :(得分:1)

代码通过将未分配的内存设置为零来激发未定义的行为:

memset( & worker, 0, sizeof( worker_t ) );

上面这一行最有可能通过将sizeof(worker_t)字节 写入指向{{1}的指针的地址 来掩盖程序的内存管理。已经分配了字节,而不是指针所指向的位置。

这样做也会覆盖对内存分配的引用。它不再可访问,因此不能再worker_t ed并且程序泄漏了这个内存。

将新分配的结构清零:

free()

memset(worker, 0, sizeof(worker_t ));

或使用memset(worker, 0, sizeof(*worker)); 在分配时将其初始化为零(无需再调用calloc()

memset(worker, 0, ...)

worker = calloc( 1, sizeof(worker_t));

您可能想知道为什么代码还没有在这里:

worker = calloc( 1, sizeof(*worker));

请注意,上面使用的printf( "Mutex (%d)\n", (int) sizeof w->worker_mutex ); 表达式在编译期间已经计算,因为它是常量。

所以1 st 时间(sizeof(...) - 指针)NULL试图被解除引用是在这里:

w

这样做会导致观察到的分割vilolation。