【问题标题】:pthread_join void **retvalpthread_join 无效 **retval
【发布时间】:2016-09-17 15:52:29
【问题描述】:

我在尝试访问 pthread_join 的第四个参数时遇到了分段错误。这是我的代码:

void* threadHandler(void* arg)
{
  printf("arg: %c\n", *(char *) arg);
  pthread_exit(0);
}

int main()
{
  pthread_t threadA;
  pthread_create(&threadA, NULL, threadHandler, "N");

  void *retval;
  pthread_join(threadA, &retval);

  printf("retval: %d\n", *(int *) retval);

  return 0;
}

知道为什么最后一个 printf 会导致分段错误吗?我如何解决它? (我的理解是retval应该包含threadHandler的返回值,所以在这种情况下应该是0吧?)

提前致谢!

【问题讨论】:

  • pthread_exit 将指向 void 的指针作为返回值。您正在返回 (void *)0,它是一个空指针。然后你取消引用空指针,这会导致未定义的行为(在这种情况下崩溃)。
  • 首先,你说threadHandler() 的返回值,但它没有返回任何会调用未定义行为的东西。最重要的是,您应该返回一个指针,而 0 可能是 NULL 指针。然后你取消引用它在理论上调用 UB 并最终导致崩溃。
  • facepalm 谢谢大家:)

标签: c segmentation-fault pthreads


【解决方案1】:

如果您了解pthread_join() 将选择线程回调的返回值,那么您应该像这样从它返回

#include <stdio.h>
#include <stdint.h>
#include <pthread.h>

void *
threadHandler(void *data)
{
    printf("arg: %s\n", (char *) data);
    return (void *) 0;
}

int 
main(void)
{
    pthread_t thread;
    const char *string;
    void *number;

    string = "N";
    if (pthread_create(&thread, NULL, threadHandler, (void *) string) != 0)
        return -1;
    pthread_join(thread, &number);
    printf("%d\n", ((int) (intptr_t) number));
    return 0;
}

但是请注意,返回的地址 0x00 可能不是有效地址 - 通常是 NULL 指针 (void *) 0x00 - 所以只要您对使用指针的值作为要返回的整数。

取消引用指针是未定义的行为,但是,使用值不是。

【讨论】:

    猜你喜欢
    • 2020-06-12
    • 2021-10-15
    • 1970-01-01
    • 2019-01-22
    • 2020-08-03
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多