当前位置: 首页 > 知识库问答 >
问题:

与(int)一样取消对void*的引用--标准实践?

司徒浩思
2023-03-14

我试图打印线程的返回值,发现我仍然对双空指针的概念感到困惑。

我的理解是,空格*是指向任何数据类型的指针,这些数据类型可以通过适当的强制转换来解除引用,但是否则引用的“级别”会像常规类型的指针一样保留下来(也就是说,你不能期望得到与放入 **(int**)Depth2通过像 *Depth2那样只取消引用一次。)。

然而,在我为线程返回打印而拼凑的代码(如下)中,当我只是将空指针强制转换为(int)时,似乎根本没有取消对空指针的引用。这是地址用作值的情况吗?如果是这样,这是从线程返回的正常方式吗?否则,我错过了什么??

(我知道在线程内操作数据的更安全的方法可能是调用方级存储,但我对这种情况非常感兴趣,我不了解void指针的含义。)

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

void *myThread(void *arg)
{
    return (void *)42;
}

int main()
{
    pthread_t tid;
    void *res;                                        // res is itself a void *

    pthread_create(&tid, NULL, myThread, NULL);
    pthread_join(tid, &res);                          // i pass its address, so void** now
    printf(" %d \n", (int)res);                       // how come am i able to just use it as plain int?

    return 0;
}

共有1个答案

汪驰
2023-03-14

首先,pthread_join()的目的是更新通过其第二个参数给出的space*,以便获得线程函数的结果(aval*)。
当你需要更新int,如scanf("%d",

在您的示例的具体情况下,我们不会以正常的方式使用返回的space*:这是一个技巧!
因为指针可以被认为是一个大整数,在一个很长的行中计数字节,技巧是假设这个指针可以简单地存储一个整数值,它不引用任何内存位置。

在您的示例中,返回(void*)42,相当于说“您将在地址42处发现有趣的内容”
但是这个地址从来没有放过任何东西<这是个问题吗?不,只要没有人试图取消引用该指针以检索地址42处的内容。

执行pthread\u join()后,变量res已更新,在本例中包含返回的void*:42
我们在这里执行相反的技巧,假设此指针中存储的信息不是指内存位置,而是一个简单的整数。

它可以工作,但这是非常丑陋的
主要优点是避免了malloc()/free()的昂贵成本

void *myThread(void *arg)
{
  int *result=malloc(sizeof(int));
  *result=42;
  return result;
}

...
int *res;
pthread_join(tid, &res);
int result=*res; // obtain 42
free(res);

避免这种开销的更好的解决方案是使用thread函数的参数。

void *myThread(void *arg)
{
  int *result=arg;
  *result=42;
  return NULL;
}

...
int expected_result;
pthread_create(&tid, NULL, myThread, &expected_result);
pthread_join(tid, NULL);
// here expected_result has the value 42

 类似资料:
  • 问题内容: 我开始使用Java(我正在学习微编辑),但在以下课程中收到此错误:“无法取消引用”: 我在这里做错了什么?好吧,我来自PHP和ECMAScripts,能够以这种方式传递函数自变量,因此我真的不理解该错误。 问题答案: 在中是你已经通过色彩值,而不是你的参考。因此,错误是当您尝试在上调用方法而无法执行时。

  • 问题内容: 在下面的代码中,我有int无法取消引用错误,这里//我有错误。我很困惑,因为变量b用于稍后在行中引用empl数组中的点,而没有显示为错误。那么,如何解决此问题,为什么会产生错误?我将不胜感激任何帮助。示例代码也很棒,因为这似乎是我学得最好的方法。谢谢! 编辑:欢迎按员工编号对数组进行排序的任何其他建议。 问题答案: 显然会传回。 是原始类型,而不是对象。 因此,您不能调用类似的方法。

  • 描述 (Description) C库函数void (*signal(int sig, void (*func)(int)))(int)设置处理信号的函数,即信号编号为sig的信号处理程序。 声明 (Declaration) 以下是signal()函数的声明。 void (*signal(int sig, void (*func)(int)))(int) 参数 (Parameters) sig

  • 问题内容: 因此,我在这里看到了一个示例,该示例如何使用Comparator接口对ArrayList进行排序,因此我进行了尝试。使用Strings可以很好地工作,但是我要排序的一个变量是Integer,它将无法编译,并说“不能取消引用int”。 我该怎么做才能使它起作用,并允许我按score变量对ArrayList进行排序? 这是我的代码: 谢谢您的帮助! 问题答案: 您不能在上调用方法;没有可以

  • 描述 (Description) C库函数int atexit(void (*func)(void))导致在程序终止时调用指定的函数func 。 您可以在任何地方注册终止功能,但会在程序终止时调用它。 声明 (Declaration) 以下是atexit()函数的声明。 int atexit(void (*func)(void)) 参数 (Parameters) func - 这是在程序终止时调

  • 我注意到当涉及到std::function对象和std::bind时,std::is_convertible和std::is_assignable会产生一些奇怪的结果。 我假设当这些函数返回true时,就可以进行转换了。还是我错过了什么? 下面的代码在不同的编译器上打印不同的结果,我希望它打印0,因为这些类型不能赋值。 它在以下编译器上打印0: null 它在以下编译器上打印 1: 4.7 VC