【问题标题】:C, casting an array of structs passed through a void pointerC,强制转换通过 void 指针传递的结构数组
【发布时间】:2013-06-29 09:59:47
【问题描述】:

我陷入了一个简单的指针/转换问题:

我尝试将一个包含 2 个结构的数组作为参数传递给 pthread_create 中的 pthread 函数。代码如下:

struct sockaddr_in addr_left, addr_right;
struct sockaddr_in* addr_vec [2] = {&addr_left, &addr_right};
pthread_create (&thread_forward,   NULL, thread_func_forward, (struct sockaddr**)addr_vec); 

thread_func_forward 内部:

void * thread_func_forward (void * argv) {
  struct sockaddr_in* addr_left = ((struct sockaddr_in*)argv + 0);
  struct sockaddr_in* addr_right = ((struct sockaddr_in*)argv + 1);
}

由于某种原因它不能正常工作,程序可以执行最后几行而不会出现分段错误,但是当我访问结构的成员时,它们完全改变了

【问题讨论】:

  • 我猜addr_left、addr_right和数组是函数的局部变量,在栈上。当你从这个函数返回时,这些堆栈变量已经消失/垃圾。
  • 您是否尝试过使用普通函数调用而不是线程?效果好吗?

标签: c pointers struct pthreads


【解决方案1】:

您没有将线程参数转换回正确的类型。您的代码将线程参数强制转换为struct sockaddr_in *,但这不是正确的类型。 addr_vec 是一个指针数组,所以addr_vec 会衰减成一个指向指针的指针。

由于您传递的是指向指针的指针,因此您应该在线程函数中将其转换为这样。然后,你需要解引用它以获得你想要的指针。

  struct sockaddr_in* addr_left = *((struct sockaddr_in**)argv + 0);
  struct sockaddr_in* addr_right = *((struct sockaddr_in**)argv + 1);

这些是从创建线程的函数指向本地自动变量的指针,这可能是也可能不是问题。这取决于该函数是否在这些变量超出范围之前等待线程完成。

【讨论】:

    【解决方案2】:

    您的addr_vec 存在于自动存储中(即在堆栈上),但没有迹象表明您已采取任何措施来确保变量的生命周期至少持续到您访问它们的时间点在线程中。

    简而言之,您需要在创建线程之前动态分配,然后在线程中释放它,或者使用同步原语来防止创建线程的函数在您在线程本身中获取副本之前返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-15
      • 2018-03-05
      • 2021-10-26
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      相关资源
      最近更新 更多