【问题标题】:Segfault updating an int pointer in c段错误更新 c 中的 int 指针
【发布时间】:2016-05-19 22:12:19
【问题描述】:

我正在使用的测试程序有点问题。如果我尝试取消引用指针以更新其值会导致段错误。

这是被调用的函数:

// Extracts a message from the community mailbox
void mbox_withdraw(struct mbox *mb, char *msg, int *len)
{
  // Locks the semaphore
  sem_wait(lock);

  // If message node is null, there is no message, just return
  if (mb->msg != NULL)
  {
    int var = strlen((mb->msg)->message);
    len = &var;
    strncpy(msg, (mb->msg)->message, len + 1);


    // If there is only one message node
    if ((mb->msg)->next == NULL)
    {
      (mb->msg)->message = NULL;
      free((mb->msg)->message);
      mb->msg = NULL;
      free(mb->msg);
    }

    // There are more than one message, just take the first one
    else
    {
      struct messageNode *temp = mb->msg;
      mb->msg = (mb->msg)->next;
      temp->message = NULL;
      free(temp->message);
      temp->next = NULL;
      free(temp);
    }
  }
  // Unlocks the semaphore
  sem_signal(lock);
}

这是调用函数:

int main(void) {

   t_init();

   mbox_create(&mb);
   t_create(producer, 1, 1);
   t_create(producer, 2, 1);
   t_create(consumer, 3, 1);
   t_yield();

   int len;
   char mesg[1024];
   mbox_withdraw(mb, mesg, &len); // should print a warning about the mailbox not having any messages

   mbox_destroy(&mb);

   t_shutdown();
   printf("Done with mailbox test...\n");
   fflush(stdout);

   return 0;
}

如果我使用:

int var = strlen((mb->msg)->message);
        len = &var;

没有段错误,但这当然不是更新值的正确方法。如果我使用:

int var = strlen((mb->msg)->message);
        *len = var;

这是我在这个网站上的第一篇文章,如果这篇文章看起来很尴尬,请原谅。

【问题讨论】:

    标签: c pointers pass-by-reference


    【解决方案1】:

    在函数中,len 是一个指针。你在这里做什么:

    int var = strlen((mb->msg)->message);
    len = &var;
    strncpy(msg, (mb->msg)->message, len + 1);
    

    正在将 var 的地址分配给 len 指针(例如,它可以是 0x12345678),然后使用指针(包含 0x12345678)作为值(试图从 (mb->msg 复制 0x12345678+1 数据)->message to msg),导致段错误。

    第二种方式是对的,将var值赋给len指针值(不是地址),但是你必须这样做:

    strncpy(msg, (mb->msg)->message, *len + 1);
    

    获取指针的值。

    【讨论】:

    • 是的,这正是问题所在。我试图修复错误的线路。谢谢
    【解决方案2】:

    未编译测试,但仅使用我的手机。我对 strncpy 调用的反应更多。如果使用带有 -Wall 标志的 gcc 应该给出警告

    len = &var;
    strncpy(msg, (mb->msg)->message, len + 1);
    

    进入

    *len = var;
    strncpy(msg, (mb->msg)->message, *len + 1);
    

    或者

    *len = var;
    strcpy(msg, (mb->msg)->message);
    

    【讨论】:

      【解决方案3】:

      我认为段错误不是由您指定的行产生的。如果您使用gcc,则最好使用gdb 进行调试或使用valgrind 之类的内存仿真运行。然后你会看到哪一行出现了段错误。

      如果len设置不正确,会产生后果。我想您删除了一些行,但是对于所述示例 len 没有意义,因为它只使用一次,您可以在这里写:

      strncpy(msg, (mb->msg)->message, var + 1);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        • 2012-04-10
        相关资源
        最近更新 更多