【问题标题】:Dereferencing struct void pointer in C在C中取消引用struct void指针
【发布时间】:2013-09-08 20:20:44
【问题描述】:

我有一个 MyLib.h,其中有

typedef void *MyThread;

还有一个 MyLib.c,它有:

typedef struct
{
ucontext_t *context;
int tid;
}_MyThread;

有一个测试函数可以创建一个线程并发出一个连接:

void f0(void * dummy)
{
  MyThread t1;
  printf("f0 start\n");
  t1 = MyThreadCreate(f1, NULL);
  _MyThread *t = (_MyThread*)t1;
  printf("passed value=%d\n",t->tid);

  printf("f0 join on t1\n");
  MyThreadJoin(t1);
....
}

MyLib.c中的MyThreadCreate和MyThreadJoin如下:

MyThread MyThreadCreate(void(*start_funct)(void *), void *args)
{
   _MyThread child_thread; 
   ... 
   //setting the child thread's tid 
   child_thread.tid = ++active_threads;
   ... MyThread ret = (MyThread)&child_thread;
   return ret;
}

int MyThreadJoin(MyThread thread)
{
    _MyThread *arg_thread;
    arg_thread = (_MyThread*)thread;
    int id = arg_thread->tid;
....
}

我的问题是,当我运行上述内容时,我得到:

passed value=2
f0 join on t1
arg_thread->tid = 13

传递的值 = "2" 是正确的,但是库函数中出现的值 "13" 是错误的。为什么传递的值以相同的方式解引用,与调用函数不同,在被调用函数中不同?

【问题讨论】:

  • 您将一个指针传递给一个指针 (a void**),但该函数接受一个指针 (a void*)。 (编辑:实际上,也许不是。仍在尝试理解您的代码……)
  • 好吧,你将void* 转换为void**,而不是指向它。你应该做t = &t1arg_thread = &thread;。使用您当前的代码,您正在到处切换指针类型并弄乱内存。
  • 传递的值,即函数 f0 是正确的。但是,它在 MyThreadJoin 函数中打印错误。
  • 您是否将相同的结构传递给不同的线程?如果是这样,您就会遇到同步问题。
  • 正如我所说,你的演员阵容是错误的。无需使用任何类型转换即可编写此代码。尝试这样做,您的问题就会消失。今后,我强烈建议不要将指针隐藏在 typedef 后面,并使用前向声明而不是使用 void 指针。

标签: c pointers void-pointers


【解决方案1】:

能否添加代码打印出arg_thread和t的内存地址。我有一种感觉是你的指针被一个演员切成两半。 MyThreadJoin 是否在 MyLib.h 中正确声明?您是否将代码编译为 64 位?

[编辑] 我刚刚在您创建 t 的地方看到了您的评论。看起来您正在将它分配在堆栈上(而不是堆上)。当你上一个堆栈帧时,它的内存还没有被覆盖。当你将一个新函数压入堆栈时,它会覆盖 t 上的内存。简单的解决方案是在构造函数中 malloc 结构。

【讨论】:

  • 我尝试打印两者的地址,两者的地址相同,f0 中的 t 和 MyThreadJoin 函数中的 arg_thread 。是的,我在 64 位机器上编译。
  • 谢谢。你现在说的话很有道理。我实际上测试了多次调用 MyThreadCreate 和 MyThreadJoin,我得到的值保持不变。您能否用简短的代码解释一下我应该如何解决这个问题?
猜你喜欢
  • 2012-05-23
  • 1970-01-01
  • 2011-06-17
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
相关资源
最近更新 更多