【问题标题】:Pthread struct argument with void*带有 void* 的 Pthread 结构参数
【发布时间】:2019-03-23 18:29:15
【问题描述】:

喂,

我想知道这样的事情是否可能,而不使用 heap(malloc/calloc) 假设我有一个结构 像这样:

typedef struct {
  void* par1_;
  void* par2_;
}parameters;

还有一个位置:

typedef struct {
  short x;
  short y;
}position;

这是一个被线程调用的函数。

void* car(void* arg)
{
   parameters car_type = *((parameters*) arg);
   int first_par = *(int*)&car_type.par1_;
   int second_par = *(int*)&car_type.par2_;   // can I do this?
   //if yes how do I extract now values from position struct "pos.x and pos.y" 
}

从我的主线程中,我想在结构“位置”中标记位置,将该结构分配给第二个参数“par2_”,然后将其发送到我的功能车。

int main()
{
  parameters pars;
  position pos;

  pos.x = 44;
  pos.y = 25;

  pars.par1_ = (void*) CAR_TYPE; // Global Variable
  pars.par2_ = &pos;   // not sure about this?

  pthread_t tid;
  pthread_create(&tid, NULL, car, (void*) &pars);

  pthread_join(tid, NULL);

如果这是一个愚蠢的问题,我很抱歉。显然我对这一切都很陌生。再一次,我不想使用堆。这是我的程序的最小示例。

【问题讨论】:

  • 在分配position 的地址时,为什么要将car_type.par2_ 转换为int*
  • 可能不会将堆栈变量的地址传递给线程。我不知道会发生什么,但这似乎是个坏消息。
  • @Swordfish 大脑冻结!感谢您指出这一点,现在一切都清楚了。
  • @DenzZuckerpuppe Kein 问题,Pueppchen。

标签: c struct pthreads void


【解决方案1】:

我想你想要更多这样的东西;

void* car(void* arg)
{
   parameters car_type = *((parameters*) arg);
   int first_par = car_type.par1_; // This is CAR_TYPE is it really an int?
   position *second_par = (position *)car_type.par2_; 

   second_par->x, second_par->y;
}

虽然您可能只想更改参数结构以包含您真正想要的类型。

typedef struct {
  int par1_;
  position* par2_;
}parameters;
void* car(void* arg)
{
   parameters car_type = *((parameters*) arg);
   int first_par = car_type.par1_; // This is CAR_TYPE is it really an int?
   car_type.par2_->x; //access like this
}

【讨论】:

  • 这是一个学校项目。无法添加/修改任何结构。在我发布我应该创建位置线程并为其分配第二个参数的问题后,它立即单击。谢谢!
【解决方案2】:

不知道你在问什么,所以我会给你标准的建议,似乎与情况有关。

终身

在将指针传递到堆栈内存时要非常小心。始终牢记以下三点:

  1. 什么会使用指针?
    它将用于什么?哪些功能最终会得到它?您需要知道这一点才能处理接下来的两点。
  2. 指针将存储在哪里?
    如果指针永远不会离开堆栈,那很好。如果指针存储在堆内存中,有可能超过堆栈帧,就会敲响警钟。 如果指针超过堆栈帧,可怕的意外数据损坏是正常的。不要让这种情况发生。
  3. 什么时候使用指针?
    首次使用内存的堆栈帧中的任何内容或调用的任何内容都可以。除此之外的任何东西,内存都不是你可以玩的。确保您永远不会EVER EVER返回指向您刚刚获得的堆栈内存的指针。

重申:

做:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int nums = {12, 630, 43, 0};
    printf("%d", sum(nums));
}

int sum(int *num_pointer) {
    int count = 0;
    for (; *num_pointer; num_pointer += 1) {
        add(&count, *num_pointer);
    }
    return count;
}

void add(int *a, int b) {
    *a += b;
}

不要:

int main(int argc, char *argv[]) {
    print_int(get_int(7));
}

int *get_int(int value) {
    return &value;
}

void print_int(int *num) {
    printf("%d", *num);
}

另外,不要在不必要的时候进行类型转换。这是一个指向糟糕程序设计的大迹象;考虑修改它。

【讨论】:

  • 我认为你的意思是写 Lifetime 而不是 Scope。因为它们是完全不同的东西。
  • @AjayBrahmakshatriya 正确。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多