【发布时间】:2022-01-31 22:03:47
【问题描述】:
我有以下发件人:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <errno.h>
typedef struct message {
long int mtype;
int mtext[200];
} message;
int main(int argc, char *argv[]) {
// msg queue
int msgid;
message msg;
key_t key;
// create msg queue key
if ((key = ftok("master.c", 'b')) == -1) {
perror("ftok");
}
// create msg queue
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget");
}
msg.mtype=10;
msg.mtext[0] = 1;
if ((msgsnd(msgid, &msg, sizeof(message), 0)) == -1) {
perror("msgsnd");
}
sleep(5);
// TODO: uncomment section
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl");
}
return 0;
}
和接收者:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <errno.h>
typedef struct message {
long int mtype;
int mtext[200];
} message;
int main(int argc, char *argv[]) {
// msg queue
message msg;
int msgid;
key_t key;
// create msg queue key
if ((key = ftok("master.c", 'b')) == -1) {
perror("ftok");
}
// create msg queue
if ((msgid = msgget(key, 0666)) == -1) {
perror("msgget");
}
if ((msgrcv(msgid, &msg, sizeof(message), 10, 0)) == -1) {
perror("msgrcv");
}
printf("%d\n", msg.mtext[0]);
return 0;
}
问题是当我同时运行它们时,我得到了
*** stack smashing detected ***: terminated
Aborted (core dumped)
上面的短语是在整个代码按预期执行之后显示的,但这仍然意味着有些事情是不正确的。但是,如果我将msgrcv 置于无限循环中,一切都会按预期运行并且不会引发警告。由于我正在写入和读取相同大小的数据,错误可能来自哪里?
【问题讨论】:
-
为什么你使用
int数组而不是uint8_t更有意义? -
总的来说,这是使用“struct hack”的腐烂的 C99 之前的 API...另一个 *nix facepalm API...
-
@AdrianMole 是的!那是导致错误的原因。我以为我已经检查过了但没有工作,但我一定是做错了什么。谢谢!
-
@Lundin 很抱歉,我不明白您的第二条评论。但是,首先,为什么
uint8_t更有意义?你能给我发一份参考资料来看看吗? -
这个蹩脚的手册页:linux.die.net/man/2/msgrcv 说该函数需要
struct msgbuf { long mtype; char mtext[1]; };,这反过来表明发明这些函数的人是无能的。不仅因为 struct hack,还因为实现定义的 char 符号和 long 的大小,这可能在 *nix 实现之间有所不同。这只是slop,除了unsigned char的数组之外,我不会将任何东西传递给这些函数,或者谁知道可能会破坏什么。
标签: c message-queue