【问题标题】:Integers are set to random values after msgrcv在 msgrcv 之后将整数设置为随机值
【发布时间】:2012-05-18 06:42:12
【问题描述】:

我想要使用的队列中有许多消息(整数),我想使用整数 int consumed 来跟踪我使用了多少消息。

我首先使用ds.msg_qnum > 0 检测队列是否有消息,其中ds 是struct msqid_ds 的对象。如果有消息,那么我调用 msgrcv 来消费消息并增加消费计数器。

所以我有这个:

msgrcv(msgqid, (void *) &message, sizeof(message), 1, 0)
printf("consumed before incr: %d\n", consumed);
consumed++;

每次消息消费后,消费都会显示为相同的随机整数值。另外,我将消息结构设置为将消息数据保存为 int 类型;我不确定这是否是确凿的证据。

【问题讨论】:

  • message 是如何声明和初始化的?
  • 声明:typedef struct msgbuf { long mtype; int mdata; } message_buf; 初始化:message_buf message;

标签: c unix ipc


【解决方案1】:

您对msgrcv 的呼叫无效。尺寸参数错误:

struct mymsg {
    long    mtype;     /* Message type. */
    char    mtext[1];  /* Message text. */
}

[...] 参数 msgsz 指定 多行文本 的字节大小。

您应该传递msgbuf.mdata 的大小,而不是整个结构的大小。这很可能会覆盖message 的末尾,并且会乱码存储在那里的任何内容。

(确保在调用 msgrcv 之前初始化 message.mtype。)

【讨论】:

  • 从手册页中添加:msgsz 参数指定 mtext 的大小(以字节为单位)。
  • 谢谢,我只将传递大小改为msgbuf.mdata,就可以成功了。我相信我在某处读到消​​息结构是有效的,只要声明了 long 类型并且数据的类型是任意的。我仍然不确定为什么数据会改变我的整数,因为我的msgsnd 也在发送结构的整个大小。你能澄清一下吗?
  • msgsnd 必须也只传递有效载荷的大小,而不是整个结构。您在发送方的int 末尾发送数据(未定义的行为),并告诉msgrcv 您在接收方的mtext 中有那么多空间,而您却没有(未定义的行为) - 所以无论如何垃圾是在发送方中的结构转移到接收方并覆盖内存中message 之后的任何内容之后,这恰好是您的计数器。对此要非常非常小心 - 这种类型的错误可能非常难以调试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多